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

4

6 回答 6

9

因为a*b会产生一个临时的int变量,即254,也就是1111 1110。当强制转换为byte时,这将作为有符号值处理。MSB 为 1,因此其值为负数,值为 -((((inv)111 1110) + 1) = -((000 0001) + 1) = -2。

于 2013-11-05T09:46:13.950 回答
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

于 2013-11-05T09:46:38.783 回答
0

8 位中的 127 用二进制表示,如下所示:

01111111

乘以 2,你得到这个:

11111110

(以 10 为底乘以 10 时,所有数字都可以左移到下一个位置。二进制乘以 2 时自然也是如此)

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

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

于 2013-11-05T09:51:23.237 回答
0

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

于 2013-11-05T09:58:04.887 回答
0

由于 byte 是有符号类型 2 * 127 是二进制“11111110”,它是-2的二进制补码

于 2013-11-05T09:45:38.307 回答
0

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

254 = FE = 1111 1110

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

于 2013-11-05T09:45:40.113 回答