【问题标题】:Bit shift of signed byte strange behaviour有符号字节奇怪行为的位移
【发布时间】:2013-03-14 10:05:21
【问题描述】:

我写了一个函数来打印一个字节的位。这是通过将最高有效位设置为 1 将其与输入字节进行比较,如果它也是 1,则打印“1”否则为“0”。然后比较字节右移。

如何实现从 10000000 开始并转移到 01000000 然后 00100000...

我相信我的问题是由提升到 int 然后重铸造成的,但我没有看到解决方案。

package errorreporting;

public class ErrorReporting {

ErrorReporting() {
}

public static void main(String[] args) {

    ErrorReporting myError = new ErrorReporting();
    byte myByte = 16;
    myError.printByteArray(myByte);

}

public void printByteArray(byte inputByte) {
    // print out 1 or 0
    byte comparison = -128;
    for (int x = 0; x < 8; x++) {
        if ((inputByte & comparison) != 0) {
            System.out.print("1");
        } else {
            System.out.print("0");
        }
        //       System.out.print(" comparison : " + comparison);
        comparison = (byte) (comparison >>> 1);

    }
    System.out.println(" : " + inputByte);
}

}

这篇文章有一些信息:Java bitshift strangeness

【问题讨论】:

    标签: java byte bit-manipulation


    【解决方案1】:

    我相信我的问题是由提升到 int 然后重铸引起的

    是的,它是一些隐式和显式转换以及符号扩展的组合:

    1. 在移位操作发生之前,所有参数首先被提升为 int,另请参见 https://stackoverflow.com/a/3948303/1611055

    2. 由于 1.,您的无符号移位运算符 &gt;&gt;&gt; 没有帮助 - 它正确地将 0 移动到最左边的位置,但由于源参数 -128 已提升为 int 在应用轮班之前(导致0xffffff80),您在第一次轮班后得到0x7fffffc0

    最简单的解决方案是使用int 作为您的掩码:

    int comparison = 0x80;  // -128;
    

    理论上,您仍然可以使用一个字节作为掩码,但是您需要在应用移位之前将其显式转换为 int 同时丢弃符号位运算符,如下所示:

    byte comparison = -128;
    ...
    comparison = (byte)( (((int) comparison) & 0xff) >>> 1);
    

    ((int) comparison) &amp; 0xff) 假定字节确实应该是“无符号”并将其转换为相应的“无符号”int 值。然后,您可以应用移位运算符(&gt;&gt;&gt;&gt;&gt; 无关紧要,因为无论如何我们都有一个正的 int 值)并将其转换回 byte

    【讨论】:

    • 感谢这项工作,我发现 Java 对 int 进行这种自动提升有点烦人,这使得按位运算符的行为不像预期的那样,我想知道他们为什么决定这样做。跨度>
    猜你喜欢
    • 2018-03-04
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    相关资源
    最近更新 更多