[英]Why am I not able to mask 32 bits on a long data type in Java
我无法弄清楚为什么会这样。 我试图在 long 上屏蔽 java 的最低有效 32 位,但它没有正确地和第 33 位和第 34 位甚至更远。 这是我的例子
class Main {
public static void main(String[] args) {
long someVal = 17592096894893l; //hex 0xFFFFAAFAFAD
long mask = 0xFF; //binary
long result = mask & someVal;
System.out.println("Example 1 this works on one byte");
System.out.printf("\n%x %s", someVal, Long.toBinaryString(someVal) );
System.out.printf("\n%x %s", result, Long.toBinaryString(result) );
long someVal2 = 17592096894893l; //hex 0xFFFFAAFAFAD
mask = 0xFFFFFFFF; //binary
result = mask & someVal2;
System.out.println("\nExample 2 - this does not work");
System.out.printf("\n%x %s", someVal2, Long.toBinaryString(someVal2) );
System.out.printf("\n%x %s", result, Long.toBinaryString(result) );
}
}
我期望结果将最重要的字节删除为零,因为 AND 操作是在 32 位上完成的。 这是我得到的输出。
Example 1 - this works
ffffaafafad 11111111111111111010101011111010111110101101
ad 10101101
Example 2 - this does not work
ffffaafafad 11111111111111111010101011111010111110101101
ffffaafafad 11111111111111111010101011111010111110101101
我希望能够屏蔽 long 值的第一个最低有效 4 个字节。
我相信您在这里看到的是 Java 使用符号扩展将整数转换为 long 的事实。
首先,这段代码应该做什么?
int myInt = -1;
long myLong = myInt;
System.out.println(myLong);
这应该直观地打印出 -1,这确实发生了。 我的意思是,如果在将 int 转换为 long 时,我们没有得到与开始时相同的数字,那会有点奇怪。
现在,让我们来看看这段代码:
int myInt = 0xFFFFFFFF;
long myLong = myInt;
System.out.println(myLong);
这个打印什么? 嗯,0xFFFFFFFF 是有符号的 32 位数字 -1 的十六进制版本。 这意味着这段代码完全等同于上面的代码,所以它应该(并且确实)打印相同的值 -1。
但是值 -1,编码为 long,没有表示 0x00000000FFFFFFFF。 那将是 2 32 - 1,而不是 -1。 相反,因为它是 64 位长,-1 表示为 0xFFFFFFFFFFFFFFFF。 哎呀 - 所有高位刚刚被激活! 这使得它作为位掩码不是很有效。
Java 中的规则是,如果将 int 转换为 long,如果 int 的第一个位为 1,则 long 的所有 32 个高位也将设置为 1。 这样就可以将整数转换为 long 保留数值。
如果你想创建一个实际上是 64 位长的位掩码,用一个长字面量而不是一个整型字面量来初始化它:
mask = 0xFFFFFFFFL; // note the L
为什么这会有所作为? 如果没有 L,Java 会将代码视为
但是,如果包含 L,Java 会解释如下内容:
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.