为什么我无法在 Java 中屏蔽长数据类型的 32 位
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 使用符号扩展将整数转换为长整数。
对于初学者,这段代码应该做什么?
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.
但是编码为 long 的值 -1 没有表示 0x00000000FFFFFFFF。那将是 232 - 1,而不是 -1。相反,由于它是 64 位长,-1 表示为 0xFFFFFFFFFFFFFFFFFF。哎呀——所有的高位都被激活了!这使得它作为位掩码不是很有效。
Java中的规则是,如果将 int 转换为 long,如果 int 的第一位为 1,则 long 的所有 32 个高位也将设置为 1 .这样就可以将整数转换为长整数,从而保留数值。
如果你想制作一个实际上是 64 位长的位掩码,请使用 long 文字而不是 int 文字对其进行初始化:
mask = 0xFFFFFFFFL; // note the L
为什么这会有所不同?没有 L,Java 将代码视为
- 创建整数值 0xFFFFFFFF = -1,给 32 一个位。
- 将该整数值转换为长整型。为此,使用符号扩展将其转换为长值 -1,连续给出 64 个一位。
但是,如果包含 L,Java 会解释如下:
- 创建 long 值 0xFFFFFFFF = 232 - 1,即 32 个零位后跟 32 个一位。
- 将该值分配给掩码。
希望对您有所帮助!
我不明白为什么会这样。我试图在 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 使用符号扩展将整数转换为长整数。
对于初学者,这段代码应该做什么?
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.
但是编码为 long 的值 -1 没有表示 0x00000000FFFFFFFF。那将是 232 - 1,而不是 -1。相反,由于它是 64 位长,-1 表示为 0xFFFFFFFFFFFFFFFFFF。哎呀——所有的高位都被激活了!这使得它作为位掩码不是很有效。
Java中的规则是,如果将 int 转换为 long,如果 int 的第一位为 1,则 long 的所有 32 个高位也将设置为 1 .这样就可以将整数转换为长整数,从而保留数值。
如果你想制作一个实际上是 64 位长的位掩码,请使用 long 文字而不是 int 文字对其进行初始化:
mask = 0xFFFFFFFFL; // note the L
为什么这会有所不同?没有 L,Java 将代码视为
- 创建整数值 0xFFFFFFFF = -1,给 32 一个位。
- 将该整数值转换为长整型。为此,使用符号扩展将其转换为长值 -1,连续给出 64 个一位。
但是,如果包含 L,Java 会解释如下:
- 创建 long 值 0xFFFFFFFF = 232 - 1,即 32 个零位后跟 32 个一位。
- 将该值分配给掩码。
希望对您有所帮助!