在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相同,掩盖 i & 0x1F
,当给定一个恒定值时,它在编译时提供警告:
warning: left shift count >= width of type