在 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)
这也适用于>>
and >>>
。
显然,移动 >= 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