为什么 byte b = (byte) 0xFF 等于整数 -1?

23

为什么 byte b = (byte) 0xFF 等于 integer -1

例子:

int value = byte b = (byte) 0xFF;
System.out.println(value);

它会打印出-1吗?

7个回答

22

在Java中,字节是带符号的。在二进制中,0x00表示0,0x01表示1,以此类推,但所有的1(即0xFF)表示-1,0xFE表示-2,以此类推。参见补码,这是使用的二进制编码机制。


2
当将字节扩展为整数时,Java会执行符号扩展。请参见http://en.wikipedia.org/wiki/Two%27s_complement#Sign_extension。 - shf301

13
  1. 在确定调用哪个system.out.println的重载时,b会被提升为一个int

  2. Java中所有的字节都是有符号的。

  3. 有符号字节0xff表示值为-1。这是因为Java使用二进制补码表示有符号值。有符号字节0xff代表-1,因为它最高位为1(所以它代表一个负数),其值为-128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1


5
也许你感到困惑的原因是为什么 (byte)0xFF(int)0xFFFFFFFF 相等。这里发生的是从较小的有符号类型向较大的有符号类型提升会导致较小的值被进行了符号扩展,即最高位被复制到所有新的提升值的位中。无符号类型不会进行符号扩展,它们进行零扩展,新的位将始终为零。

如果这样有助于您理解,可以这样想,任何大小的整数也都有一些“幻影”位,这些位过于重要而无法表示。它们存在,只是未存储在变量中。负数具有这些位非零,而正数在提升较小值到较大值时,这些幻影位变成了实际位。


3

1

因为Java(以及大多数语言)使用补码算术表示负整数值。在补码中,0xFF(11111111)表示(在有符号整数中)值为-1。


0

取模运算

byte = 256 0xff = 255

255 / 256 -> 余数为 255

因此 255 - 256 = -1

简单逻辑 干杯


-1

不仅仅是Java使用2的补码数学。我能想到的每个微处理器和DSP都是这样做数学的方式。因此,这也是每种编程语言所代表的方式。


2
严格来说,某些语言(例如C和C++)并未指定整数所使用的表示方式,这是与平台相关的。另一方面,Java确实指定了2的补码表示法。 - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接