考虑以下Java代码:
byte a = -64;
System.out.println(a << 1);
此代码的输出为-128
我尝试如下找出为什么这是输出:
64 = 0 1000000(MSB是符号位)
-64 = 1 1000000(Tow的补码格式)
换班后的预期输出: 1 0000000(这等于0,因为MSB只是一个符号位)
请任何人解释我缺少的东西。
答案 0 :(得分:3)
-128的二进制补码表示为10000000,因此结果是正确的。
答案 1 :(得分:2)
10000000 is -128
10000001 is -127
10000010 is -126
...
所以10000000
不是0
。它是-128
,是你的输出。
答案 2 :(得分:2)
这个程序
System.out.println(Integer.toBinaryString(-64));
System.out.println(Integer.toBinaryString(-64 << 1));
System.out.println("-64 << 1 = " + (-64 << 1));
打印
11111111111111111111111111000000
11111111111111111111111110000000
-64 << 1 = -128
你可以看到-64&lt;&lt;除了所有位已经向左移位(最低位变为0)之外,1与-64相同
答案 3 :(得分:1)
在移位运算符中,忽略符号位。所以1 1000000&lt;&lt; 1是10000000,这是-128。问题是什么?
我们的机器使用two's complement来表示数字(有符号和无符号)。为了代表一个负数机器,否定它是正数并增加1.
-128是!10000000 + 1 = 01111111 + 1 = 10000000
修改强>
我错了,只有右移操作员忽略了符号位。 10100000&lt;&lt; 1 == 01000000
对于无符号右移,有一个运算符&gt;&gt;&gt;这也改变了标志位。
11000000&gt;&gt; 1 == 10100000和11000000&gt;&gt;&gt; 1 == 01100000
答案 4 :(得分:1)
在二进制补码中,MSB不仅仅是一个符号位,你还在考虑那些补码吗?在8位二补码中,
10000000 = 0x80 = -128
答案 5 :(得分:0)
<<
表示乘以2
>>
表示除以2
并且,在移位操作期间不考虑有符号位。
答案 6 :(得分:0)
我在想。 << 1
(忽略所有细节)是“乘以2”。-64 * 2 = -128。那你为什么想知道它确实是-128?