0
public class Shift {

    public static void main(String[] args) {
        for(int i = 0; i < 32; ++i){
            System.out.println(-0x55555555 << i);
        }
    }

}

上記のコードを実行すると、次の出力が得られます

-1431655765
1431655766
-1431655764
1431655768
-1431655760
1431655776
-1431655744
1431655808
-1431655680
1431655936
-1431655424
1431656448
-1431654400
1431658496
-1431650304
1431666688
-1431633920
1431699456
-1431568384
1431830528
-1431306240
1432354816
-1430257664
1434451968
-1426063360
1442840576
-1409286144
1476395008
-1342177280
1610612736
-1073741824
-2147483648

他の値(64)でテストすると、より期待される結果が得られます

public class Shift {

    public static void main(String[] args) {
        for(int i = 0; i < 32; ++i){
            System.out.println(-0x40 << i);
        }
    }

}

出力

-64
-128
-256
-512
-1024
-2048
-4096
-8192
-16384
-32768
-65536
-131072
-262144
-524288
-1048576
-2097152
-4194304
-8388608
-16777216
-33554432
-67108864
-134217728
-268435456
-536870912
-1073741824
-2147483648
0
0
0
0
0
0

仕様 (§15.19)では、次のように述べられています。

The value of n << s is n left-shifted s bit positions; this is equivalent (even if overflow occurs) to multiplication by two to the power s.

誰かが最初の出力の理由を説明できますか?

4

1 に答える 1

2

n << s の値は、n 左シフトされた s ビット位置です。これは、(オーバーフローが発生した場合でも) 2 の s 乗と同じです。

そして、それは本当です: これは、オーバーフロー-0x55555555のために 2 を乗じた場合に得られる結果とまったく同じです。s特に、0x555555550 と 1 が交互にあるため、0 と 1 を交互に符号ビットにシフトしているため、毎回符号が反転します。

于 2013-04-17T01:07:46.740 に答える