Java 将 int 转换为字节时出现奇怪的行为?
int i =132;
byte b =(byte)i; System.out.println(b);
令人难以置信。为什么是输出?-124
int i =132;
byte b =(byte)i; System.out.println(b);
令人难以置信。为什么是输出?-124
在 Java 中,an 是 32 位。A 为 8 。int
byte
bits
Java 中的大多数基元类型都是有符号的,和 、 、 和以二的补码编码。(类型为无符号,符号的概念不适用于 。)byte
short
int
long
char
boolean
在此数字方案中,最高有效位指定数字的符号。如果需要更多位,则最高有效位 (“MSB”) 只需复制到新的 MSB。
因此,如果您有byte :并且想要将其表示为(32位),则只需将1复制到左侧24次即可。255
11111111
int
现在,读取负二进制补码数的一种方法是从最低有效位开始,向左移动直到找到前一个1,然后反转每个位。得到的数字是该数字的正版本
例如:转到 = 。这就是 Java 将显示为值的内容。11111111
00000001
-1
您可能想做的是知道字节的无符号值。
您可以使用位掩码来实现此目的,该位掩码会删除除最不重要的 8 位之外的所有内容。(0xff)
所以:
byte signedByte = -1;
int unsignedByte = signedByte & (0xff);
System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);
将打印出来:"Signed: -1 Unsigned: 255"
这里到底发生了什么?
我们使用按位 AND 来屏蔽所有无关的符号位(最不重要的 8 位左侧的 1)。当一个int被转换成一个字节时,Java会砍掉最左边的24位
1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101
由于第 32 位现在是符号位而不是第 8 位(我们将符号位设置为 0,这是正数),因此 Java 将字节中的原始 8 位读取为正值。
132
in digits(以 10 为基数)以位为单位(以 2 为基数),Java 以 32 位为单位存储:1000_0100
int
0000_0000_0000_0000_0000_0000_1000_0100
int 到 byte 的算法是左截断的;算法为二的补码(二的补码是如果最左边的位是,解释为负的一补(反转位)减去一);因此::System.out.println
1
System.out.println(int-to-byte(
))
0000_0000_0000_0000_0000_0000_1000_0100
) [)))] )1000_0100
[)))] )1000_0100
))))1000_0011
)))0111_1100
))