【问题标题】:Why does Bit-Shifting a Bit-Shifted byte result in different values depending on order of shifting?为什么根据移位顺序对移位字节进行移位会导致不同的值?
【发布时间】:2015-10-19 16:39:50
【问题描述】:

考虑以下 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”)的值,即使两个移位都不会导致二进制数字丢失?

【问题讨论】:

  • 因为你已经溢出了。

标签: java casting bit-manipulation byte bit-shift


【解决方案1】:

因为符号扩展。使用&gt;&gt;&gt; 来防止:

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

此外,您的陈述“即使两个移位都不会导致二进制数字丢失”是不正确的。所有移位操作删除一个数字。在您的情况下,丢弃的数字恰好为零。

【讨论】:

    【解决方案2】:

    ...移位都不会导致二进制数字丢失

    错误。

    所有移位操作都会导致数字被丢弃。运气不好,你所观察到的似乎只是反驳了这一点,因为0 位正在被丢弃。我认为您的问题与sign extensions 和理解算术转换&gt;&gt;&lt;&lt;,与逻辑转换&gt;&gt;&gt;)有关。执行时算术移位,符号位被扩展以保留 a 数的符号。

    引用Java的official documentation

    有符号左移运算符“>”将位模式移到 对。位模式由左侧操作数给出,而 右手操作数移位的位置数。未签名的 右移运算符“>>>”将零移到最左边的位置, 而“>>”之后最左边的位置取决于符号扩展。

    【讨论】:

    • 我不认为这是“愚蠢的运气”,这只是你的假设,而且非常有判断力。 --- Java 没有&lt;&lt;&lt; 运算符。
    • Dump luck: “好事发生的方式完全是偶然,没有经过计划或应得的”。你假设这是偶然的,不是故意的。从你的链接来看,同义词:Fluke、Happenstance。不使用“愚蠢”这个词来减少判断力。
    • 如果您仔细阅读他的问题,您会发现导致这些变量匹配的愚蠢的运气:二进制零被移走了。无论如何,我不会在这个网站上争论英语的语义,所以请随意发表另一条评论——我会忽略它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2020-01-13
    • 2021-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多