java中的int/Integer掩码是如何工作的?

问题描述 投票:0回答:1

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

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 

即使签名的值是我们拥有的其他东西

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

因此,对于无符号

int
来说,实际有符号值似乎没有发生任何变化。

掩码实际上对整数的(字节)值有任何作用吗?或者它只是标记

javac
应如何处理整数的一种方法?

java byte javac unsigned-integer
1个回答
3
投票
byte signed  = -1;// -—> 0b11111111

正确。

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

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

  1. signed
    的值转换(符号扩展)为
    int
    ;即
    0b11111111
    变为
    0b11111111111111111111111111111111
    (= 0xFFFFFFFF)

  2. 0b11111111111111111111111111111111
    (=
    0xFFFFFFFF
    ) 与
    0b00000000000000000000000011111111
    (=
    0x000000FF
    ) 进行与运算,得到
    0b00000000000000000000000011111111
    (=
    0x000000FF
    )`

  3. 0b00000000000000000000000011111111
    (=
    0x000000FF
    ) 被分配给
    unsigned

(注意:完整地写出这一点很重要,以便您了解发生了什么。)

byte resigned = (byte) unsigned;

这里也有两个步骤。

  1. 演员表

    (byte)
    转换
    0b00000000000000000000000011111111
    (=
    0x000000FF
    ) 到
    0b11111111
    (=
    0xFF
    ) 即它将
    int
    转换为
    byte

  2. 然后字节

    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
转换为
int
255
,然后将其转换回字节
-1

您还可以通过阅读 Java 语言规范的相关部分来验证这一点。 (如果您需要参考资料,请告诉我。)


掩码实际上对整数的(字节)值有什么作用,还是只是标记 javac 应如何处理整数的一种方法?

屏蔽确实起到了作用。


如果您查看

javac
编译器生成的字节码,您会看到执行
byte
int
转换、屏蔽和赋值的代码。然后在另一个方向,您会看到一个字节码来进行
int
byte
的转换。

但是,这是一个实现细节。

© www.soinside.com 2019 - 2024. All rights reserved.