[C,Java] 論理右シフトと算術右シフト

右ビットシフト演算には、論理シフト(ビット列をそのまま右方向にズラす)と
算術シフト(最上位ビットを保ったまま右方向にズラす)の2種類がある。
最上位ビットを符号とした整数を「÷2」する演算は、算術右シフトを使うと
高速に処理できるとか、で使う。
ところで、論理右シフトと算術右シフトをどうやって区別して使うのか?

RShift.c ソースコード:
#include <stdio.h>

int main () {
    int a = -1;
    unsigned int b = -1;
    printf( "a=%08x b=%08x\n", a, b );
    a >>= 1;
    b >>= 1;
    printf( "a=%08x b=%08x\n", a, b );
}

コンパイル手順:
gcc -o RShift RShift.c && ./RShift

C言語では、変数型(int/unsigned int)によって、>> 演算子で
論理右シフトが利用されるか、算術右シフトが利用されるかが
自動的に判別されるわけだ。演算子のオーバーロードとも言えるか。


RShift.java ソースコード:
class RShift {
    public static void main ( String[] args ) {
        int a = -1;
        int b = -1;
        System.out.print( "a="+Integer.toHexString(a)+" b="+Integer.toHexString(b)+"\n" );
        a >>= 1;
        b >>>= 1;
        System.out.print( "a="+Integer.toHexString(a)+" b="+Integer.toHexString(b)+"\n" );
    }
}

コンパイル手順:
javac RShift.java && java RShift

Java には、unsigned 型がないんですね。(知らなかった or 忘れてた)
論理右シフトを行うためには、>>> 演算子を使うとのこと。

このように、論理右シフトと算術右シフトを演算子で明示的に区別する方式と、
C のように変数型で自動判別する方式、どっちがいいのかな。
これまで当たり前のように後者だと思っていたけど、前者も分かりやすいかも?

(PS)
Z80のアセンブリ言語には、ビットシフトに加えて、ビットを回転させる
ローテイトの命令もあったと思う。他のCPUでも、たぶん同様かな。
C・Javaのような高級言語からはローテイトって使えないのかな?

(PS2)
Perl には unsigned 型も >>> 演算子もないので、
論理右シフトができないんですね。知らなかった。
こういう31ビット目とか微妙なところは、使わないのがイチバン分かりやすい。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 14

なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー) なるほど(納得、参考になった、ヘー)
驚いた 驚いた 驚いた 驚いた 驚いた 驚いた 驚いた
ナイス
かわいい

この記事へのコメント

perl勉強中
2013年01月23日 13:26
perlのデフォルトだと右シフト( >> )は論理シフトです。
use integer;すると算術シフトができるようになります。

この記事へのトラックバック