为什么带有波浪号的移位整数掩码转换为长 return 零? (Java,移位)

Why does a shifted integer mask with a tilde casted to a long return zero? (Java, bit shift)

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

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

如果我在控制台上打印它,它会 return 0 但我期待 4294967295 因为我的结果应该看起来像 0x00000000FFFFFFFFFL 和 2^32 - 1 等于 4294967295。当我移动一个长面具时它工作但是我不懂为什么。

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

谁能给我解释一下这种行为?

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 个位置而不会超出数字的左端。

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

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

0xffffffff~0x00000000,即 0,这就是您所看到的。

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

(0xffffffffL << 32) ==
(0xffffffffL << (32 % Long.SIZE) ==
(0xffffffffL << (32 % 64) ==
(0xffffffffL << 32) ==
0xffffffff00000000L

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