为什么带有波形符的移位整数掩码会转换为长回零? (Java,位移)

时间:2016-06-17 08:47:17

标签: java long-integer bit-shift bitmask tilde

我正在尝试创建一个掩码来查看Java中的特定位。我尝试了以下方法:

long mask = ~ (0xffffffff << 32);

如果我在控制台上打印它会返回0但是我期待4294967295,因为我的结果应该看起来像0x00000000FFFFFFFFL和2 ^ 32 - 1等于4294967295.当我移动一个长掩码时它可以工作,但我不明白为什么。

long mask = ~ (0xFFFFFFFFFFFFFFFFL << 32);

有人能解释一下这种行为吗?

2 个答案:

答案 0 :(得分:3)

Java假设如果您在ints上执行算术运算,那么您希望获得int,而不是long。 (在计算完成后将输出分配给long这一事实不会影响计算本身。)

int(32位)左移32位无效。左移int时,只使用右侧操作数的五个最低位,给出一个0到31范围内的数字。 http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.19

这就是(0xffffffff<<32)==0xffffffff~(0xffffffff<<32)==0

的原因

当移位long(64位)时,使用六个最低位,给出一个0到63范围内的数字。

如果您使用0xffffffffL,那么Java将知道生成另一个long。因此,您可以在不离开数字左端的情况下移动32个位置。

答案 1 :(得分:1)

左移是模数†数据类型的大小,例如移位32位的int无效。

(0xffffffff << 32) ==
(0xffffffff << (32 % Integer.SIZE)) ==
(0xffffffff << (32 % 32)) ==
(0xffffffff << 0) ==
0xffffffff

~的{​​{1}}为0xffffffff,即0x00000000,这就是您所看到的。

然后使用64位,应用完整的32位移位,因为它小于64:

0

†严格来说,它取最后5位为整数,最后6位为长,这对负左移的模数有所不同。