为什么根据移位顺序对移位字节进行移位会产生不同的值?

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.