如何在java中使用int/Integer掩码?

nle07wnf  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(75)

由于字节在java中是有符号的,为了获得无符号整数值,我们使用0xFF asper进行掩码:

byte signed  = -1;// -—> 0b11111111
int unsigned = signed & 0xFF;// —-> 0b11111111 & 0b11111111
System.out.println(“unsigned: ”+unsigned);//prints 255 instead of -1 since we masked earlier

但是,当无符号的int被转换为一个字节时,它似乎没有发生任何变化。

byte resigned = (byte) unsigned;
System.out.println(“resigned: ”+resigned);//same value as earlier signed = -1

仔细查看初始操作

int unsigned = signed & 0xFF;// the result of 0b11111111 & 0b11111111 is actually = 0b11111111

即使signed的值是别的值

byte  signed  = -44;// -—> 0b11010100
int  unsigned = signed & 0xFF;// the result of 0b11010100 & 0b11111111 is still actually = 0b11010100 
byte resigned = (byte) unsigned;
System.out.println(“resigned: ”+resigned);//same value as signed = -44

因此,对于unsigned int的实际有符号值,似乎没有发生任何变化。
掩码实际上对整数的(字节)值做了什么吗?或者它只是一种标记javac应该如何处理整数的方法?

gzszwxb4

gzszwxb41#

byte signed  = -1;// -—> 0b11111111

正确.

int unsigned = signed & 0xFF;// —-> 0b11111111 & 0b11111111

这是不正确的。有三个步骤。

  1. signed的值被转换(符号扩展)为int;即0b11111111变为0b11111111111111111111111111111111(= 0xFFFFFFFF)
  2. 0b11111111111111111111111111111111(= 0xFFFFFFFF)与0b00000000000000000000000011111111(= 0x000000FF)进行“与”运算,给予0b00000000000000000000000011111111(= 0x000000FF)`
  3. 0b00000000000000000000000011111111(= 0x000000FF)被分配给unsigned
    (Note:重要的是要完整地写出来,这样你才能明白发生了什么。)
byte resigned = (byte) unsigned;

这里也有两个步骤。
1.转换(byte)0b00000000000000000000000011111111(= 0x000000FF)转换为0b11111111(= 0xFF),即它将int转换为byte
1.然后字节0b11111111(= 0xFF)被分配给resigned
因此,对于unsigned int,实际的有符号值似乎没有发生任何变化。
但确实发生了一些事情!&运算符从符号扩展值0b11111111111111111111111111111111(表示-1)开始,并将其转换为0b00000000000000000000000011111111(表示255)。
你可以通过运行以下命令来 * 验证 * 发生了什么:

byte signed  = -1; // -—> 0b11111111
  int x = signed;
  System.out.println("x: " + x); // prints -1

你最终得到的值和你开始的值一样,这并不意味着什么都没有发生。确实发生了一些事情。您将byte-1转换为int255,然后将其转换回字节-1
您还可以通过阅读Java语言规范的相关章节来验证这一点。(如果你需要参考资料,请告诉我。)
掩码实际上对整数的(字节)值做了什么吗?或者它只是一种标记javac应该如何处理整数的方法?
面具真的做了一些事情。
如果您查看javac编译器生成的字节码,您将看到执行byteint转换、掩码和赋值的代码。然后在另一个方向上,您将看到一个字节码,用于执行intbyte的转换。
然而,这是一个实现细节。

相关问题