考虑这个Java代码:
byte a = (byte) 0b01111110; //Binary Literal
byte b1 = (byte) (a << 1);
byte c1 = (byte) (a >> 1);
byte b2 = (byte) (b1 >> 1);
byte c2 = (byte) (c1 << 1);
System.out.println("A:" + a + " B1:" + b1 + " C1:" + c1 + " B2:" + b2 + " C2:" + c2);
结果输出为:
A:126 B1:-4 C1:63 B2:-2 C2:126
为什么字节&#39; b2&#39;有一个不等于&#39; a&#39;的值。 (以及&#39; c2&#39;在这种情况下)即使两个班次都没有导致二进制数字被删除?
答案 0 :(得分:4)
因为符号扩展。使用>>>
来阻止:
byte a = (byte) 0b01111110; // 0b01111110 = 126
byte b1 = (byte) (a << 1); // 0b11111100 = -4 <-- overflow
byte c1 = (byte) (a >> 1); // 0b00111111 = 63
byte b2 = (byte) (b1 >> 1); // 0b11111110 = -2 <-- sign extension
byte c2 = (byte) (c1 << 1); // 0b01111110 = 126
byte x = (byte) (b1 >>> 1); // 0b01111110 = 126 <-- no sign extension
此外,您的陈述“即使两个班次都没有导致二进制数字被删除”也是不正确的。所有班次操作将删除一个数字。在你的情况下,丢弃的数字恰好为零。
答案 1 :(得分:-1)
...两个班次都没有导致二进制数字被删除
所有班次操作都会导致数字被删除。通过愚蠢的运气,你所观察到的只是反驳了这一点,因为0
位被删除了。我认为您的问题必须与sign extensions一致,并理解算术转换(>>
和<<
,与逻辑转变({ {1}})。执行算术移位时,会扩展符号位以保留数字的签名。
引用Java的official documentation:
签名的左移运营商&#34;&lt;&lt;&#;将位模式向左移动, 和签名的右移操作员&#34;&gt;&gt;&#34;将位模式转换为 对。位模式由左侧操作数和 由右手操作数移动的仓位数。未签名的 右移运算符&#34;&gt;&gt;&gt;&#34;将零移动到最左边的位置, 而在&#34;&gt;&gt;&#34;之后的最左边的位置取决于符号扩展。