最近我对位操作和算术产生了兴趣。我打算用一个64位长的变量来编写代表棋盘的代码,其中每个位代表一个单元格。
我遇到了如下问题:
public class Chess {
public static void main(String[] args) {
long v = (1 << 63 ) - 1;
System.out.println(Long.MAX_VALUE+ " " +v);
System.out.println(Long.toBinaryString(v));
System.out.println(Long.bitCount(v));
}
}
以下是上述代码的输出:
9223372036854775807 2147483647
1111111111111111111111111111111
31
这是不正确的。
我期待64位二进制字符串。我正在使用64位Windows操作系统64位机器。
请帮忙。
答案 0 :(得分:5)
您有一个int
字面值,因此在尝试按63
进行位移时,只考虑63
的最后5位 - 31
。
使用long
字面值(追加“L”)进行位移:
long v = (1L << 63 ) - 1;
JLS, Section 15.19,涵盖了位移细节:
如果左侧操作数的提升类型为int,则只使用右侧操作数的五个最低位作为移位距离。
(强调我的)
这是有道理的 - int
或2 ^ 5只有32位。
此外,
如果左侧操作数的提升类型很长,则只使用右侧操作数的六个最低位作为移位距离。
这又有意义 - long
或2 ^ 6中有64位。