繁体   English   中英

为什么我不能在 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 使用符号扩展将整数转换为 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 会将代码视为

  1. 创建整数值 0xFFFFFFFF = -1,给出 32 个 1 位。
  2. 将该整数值转换为 long。 为此,请使用符号扩展将其转换为 long 值 -1,连续提供 64 个一位。

但是,如果包含 L,Java 会解释如下内容:

  1. 创建长值 0xFFFFFFFF = 2 32 - 1,即 32 个零位后跟 32 个 1 位。
  2. 将该值分配给掩码。

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM