0

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

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

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

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

谁能解释我这种行为?

4

2 回答 2

3

Java 假设如果你在 上执行算术运算ints,那么你想得到一个int返回,而不是一个long. (在计算完成后将输出分配给 a 的事实long不会影响计算本身。)

将 an 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

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

如果你使用0xffffffffL,那么 Java 就会知道产生另一个long。因此,您可以移动 32 位而不会离开数字的左端。

于 2016-06-17T08:52:13.183 回答
1

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

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

~of 0xffffffffis 0x00000000,即0你所看到的。

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

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

† 严格来说,int 采用最后 5 位,long 采用最后 6 位,这与负左移的模数不同。

于 2016-06-17T09:01:13.040 回答