这是我的代码:
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
?
答案 0 :(得分:9)
因为a*b
将导致一个临时的 int 变量,即254,即1111 1110.当转换为字节时,这将作为签名处理价值。 MSB为1,因此其值为负,值为 - (((inv)111 1110)+ 1)= - ((000 0001)+ 1)= -2。
答案 1 :(得分:3)
a * b
为254,因此您的代码为:
byte c=(byte)254;
十进制254是二进制 11111110 ,即:-2。为什么呢?
首先,这个数字是负数,因为它以1(二进制补码)开头,然后是:
¬ 1 1 1 1 1 1 1 0
是0 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 。
答案 2 :(得分:0)
由于byte是带符号的类型,2 * 127是二进制“11111110”,对于-2是two's complement。
答案 3 :(得分:0)
因为字节是有符号的,而不是无符号的。
254 = FE = 1111 1110
第一个'1'
将数字表示为负数。
答案 4 :(得分:0)
以8位为单位的127以二进制表示,如下所示:
01111111
乘以2,你就明白了:
11111110
(当您在基数10中乘以10时,所有数字都可以向左移动到下一个位置。当您在二进制中乘以2时,自然也是如此)
Java使用2的补码来表示负数。基本上,最左边的位是符号位(0代表+,1代表 - )。要转换负数的正数,请翻转所有位并添加一个。
示例:00000010
= 2,翻转位:11111101
,然后添加一个:11111110
= -2。这与上面的127 * 2相同。
答案 5 :(得分:0)
我认为您试图询问的是为什么溢出的8位有符号整数将转为负数
与CPU一样,没有8位ALU,因此8位将扩展为32位,操作后将低8位返回给用户。
在CPU中:0000_007F * 0000_0002 = 0000_00FE
这是有符号8位的溢出,但已经计算了该值
返回值为FE
对于8位签名,FE
为-2
。