为什么根据移位顺序对移位字节进行移位会产生不同的值?
Why does Bit-Shifting a Bit-Shifted byte result in different values depending on order of shifting?
考虑这个 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
为什么字节 'b2' 的值不等于 'a' 的值(在本例中为 'c2'),即使两个移位都不会导致二进制数字被丢弃?
因为符号扩展。使用 >>>
来防止:
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
此外,您的说法 "even though neither shift causes a binary digit to get dropped" 不正确。所有的移位操作都会丢掉一个数字。在您的情况下,丢弃的数字恰好为零。
...neither shift causes a binary digit to get dropped
错误。
所有移位操作都会导致数字丢失。运气不好,你所观察到的只是似乎反驳了这一点,因为 0
位被丢弃了。我认为您的问题必须与 sign extensions 相关,并理解 算术移位 (>>
和 <<
,与 逻辑移位 (>>>
)。执行算术移位时,符号位被扩展以保留数字的符号性。
引用Java的official documentation:
The signed left shift operator "<<" shifts a bit pattern to the left,
and the signed right shift operator ">>" shifts a bit pattern to the
right. The bit pattern is given by the left-hand operand, and the
number of positions to shift by the right-hand operand. The unsigned
right shift operator ">>>" shifts a zero into the leftmost position,
while the leftmost position after ">>" depends on sign extension.
考虑这个 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
为什么字节 'b2' 的值不等于 'a' 的值(在本例中为 'c2'),即使两个移位都不会导致二进制数字被丢弃?
因为符号扩展。使用 >>>
来防止:
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
此外,您的说法 "even though neither shift causes a binary digit to get dropped" 不正确。所有的移位操作都会丢掉一个数字。在您的情况下,丢弃的数字恰好为零。
...neither shift causes a binary digit to get dropped
错误。
所有移位操作都会导致数字丢失。运气不好,你所观察到的只是似乎反驳了这一点,因为 0
位被丢弃了。我认为您的问题必须与 sign extensions 相关,并理解 算术移位 (>>
和 <<
,与 逻辑移位 (>>>
)。执行算术移位时,符号位被扩展以保留数字的符号性。
引用Java的official documentation:
The signed left shift operator "<<" shifts a bit pattern to the left, and the signed right shift operator ">>" shifts a bit pattern to the right. The bit pattern is given by the left-hand operand, and the number of positions to shift by the right-hand operand. The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.