Java の場合:
(0xFFFFFFFF << 1) = 0xFFFFFFFE = 0b1111111111111110
: : :
(0xFFFFFFFF << 30) = 0xE0000000 = 0b1110000000000000
(0xFFFFFFFF << 30) = 0xC0000000 = 0b1100000000000000
(0xFFFFFFFF << 31) = 0x80000000 = 0b1000000000000000
でも:
(0xFFFFFFFF << 32) = 0xFFFFFFFF = 0b1111111111111111
論理的にはこれは意味がありませんが、Java が次のような操作を実行していると私は信じています。
a << (b % Integer.SIZE)
[編集、どうやら:]a << (b & 0x1F)
>>
これはとにも当てはまり>>>
ます。
明らかに >= 32 (整数の場合) だけシフトすると、データ型からすべてのデータが削除されますが、これが役立つ場合もあります。例えば:
int value = 0x3F43F466; // any value
int shift = 17; // any value >= 0
int carry = value & (-1 << (Integer.SIZE - shift));
if (carry > 0)
; // code...
もちろん、これは修正できますが、これらのバグを見つけるにはかなりの時間がかかります (同様のバグを追跡するのに何時間も費やしました)。それで、私の質問:すべてのビットをシフトアウトするときに論理値を返さない理由はありますか?
アップデート:
以下を使用して、C99でこれを試しました:
#include<stdio.h>
main()
{
int i, val;
for (i = 0; i <=36; i++) {
val = (-1 << i);
printf("%d :\t%d\n", i, val);
}
}
Java と同じように動作し、 masking であることがわかりましたがi & 0x1F
、定数値を指定するとコンパイル時に警告が表示されます。
warning: left shift count >= width of type