为什么将127乘以2并转换为字节后结果为-2?

3
这是我的代码:
public class test {

  public static void main(String[] args) {
    byte a=(byte)127, b=2;    
    byte c=(byte)(a*b);

    System.out.println(c);
  }    
}

为什么结果是-2

一个字节只有八个比特长。 - user1907906
字节溢出和二进制补码会导致负数。 - Sajad Bahmani
你知道吗,你的(64位?)CPU 在处理字节时会遇到困难吗? - Ingo
参见:为什么~True的结果是-2? - hippietrail
6个回答

9

因为a * b将导致一个临时的int变量,即254,它是1111 1110。当转换为byte时,这将被处理为signed值。MSB为1,所以它的值将是负数,值为-(((inv)111 1110) + 1) = -((000 0001) + 1) = -2。


3

a * b 等于 254,那么你的代码应该是:

byte c=(byte)254;

十进制数 254 对应的二进制数是 11111110,也就是 -2。为什么呢?

首先,这个数是负数,因为它以 1 开头(补码表示),然后:

¬ 1 1 1 1 1 1 1 00 0 0 0 0 0 0 1

0 0 0 0 0 0 0 1
              1 +
---------------
0 0 0 0 0 0 1 0 

这个数在十进制下表示为2,但要记住最高有效位(MSB)是1。因此最终结果是-2


0

8位二进制中的127表示为:

01111111

乘以2,你就得到了这个:

11111110

在十进制中,当你乘以10时,所有数字都可以向左移动到下一个位置。同样,在二进制中,当你乘以2时也是如此。

Java使用2的补码来表示负数。基本上,最左边的位是符号位(0表示正数,1表示负数)。要将正数转换为负数,翻转所有位并加一。

例如:00000010 = 2,翻转位:11111101,然后加一:11111110 = -2。这与上面的127 * 2相同。


0

由于byte是有符号类型,2 * 127的二进制表示为"11111110",这是二进制补码表示-2。


0

因为字节是有符号的,而不是无符号的。

254 = FE = 1111 1110

第一个 '1' 表示该数字为负数。


0

我认为你想问的是为什么8位有符号整数溢出后会变成负数。
因为在CPU中,没有8位ALU,所以8位将被扩展到32位,在操作后,将低8位返回给用户。
在CPU中:0000_007F * 0000_0002 = 0000_00FE
这是有符号8位的溢出,但值已经计算出来了。
所以返回的值是FE
对于8位有符号数,FE-2


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