由于字节在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
应该如何处理整数的方法?
1条答案
按热度按时间gzszwxb41#
正确.
这是不正确的。有三个步骤。
signed
的值被转换(符号扩展)为int
;即0b11111111
变为0b11111111111111111111111111111111
(= 0xFFFFFFFF)0b11111111111111111111111111111111
(=0xFFFFFFFF
)与0b00000000000000000000000011111111
(=0x000000FF
)进行“与”运算,给予0b00000000000000000000000011111111
(=0x000000FF
)`0b00000000000000000000000011111111
(=0x000000FF
)被分配给unsigned
。(Note:重要的是要完整地写出来,这样你才能明白发生了什么。)
这里也有两个步骤。
1.转换
(byte)
将0b00000000000000000000000011111111
(=0x000000FF
)转换为0b11111111
(=0xFF
),即它将int
转换为byte
。1.然后字节
0b11111111
(=0xFF
)被分配给resigned
。因此,对于unsigned int,实际的有符号值似乎没有发生任何变化。
但确实发生了一些事情!
&
运算符从符号扩展值0b11111111111111111111111111111111
(表示-1)开始,并将其转换为0b00000000000000000000000011111111
(表示255)。你可以通过运行以下命令来 * 验证 * 发生了什么:
你最终得到的值和你开始的值一样,这并不意味着什么都没有发生。确实发生了一些事情。您将
byte
值-1
转换为int
值255
,然后将其转换回字节-1
。您还可以通过阅读Java语言规范的相关章节来验证这一点。(如果你需要参考资料,请告诉我。)
掩码实际上对整数的(字节)值做了什么吗?或者它只是一种标记javac应该如何处理整数的方法?
面具真的做了一些事情。
如果您查看
javac
编译器生成的字节码,您将看到执行byte
到int
转换、掩码和赋值的代码。然后在另一个方向上,您将看到一个字节码,用于执行int
到byte
的转换。然而,这是一个实现细节。