Java 有符号字节的位移位行为

Java 有符号字节的位移位行为,java,byte,bit-manipulation,Java,Byte,Bit Manipulation,我已经编写了一个函数,可以将位以字节形式打印出来。通过将最高有效位设置为1,将其与inputbyte进行比较,如果它也是1,则打印“1”,否则打印“0”。然后将比较字节右移 如何实现从10000000开始到01000000再到00100000 我相信我的问题是由提升到int然后重铸造成的,但我看不到解决办法 package errorreporting; public class ErrorReporting { ErrorReporting() { } public static voi

我已经编写了一个函数,可以将位以字节形式打印出来。通过将最高有效位设置为1,将其与inputbyte进行比较,如果它也是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);
}
包错误报告;
公共类错误报告{
错误报告(){
}
公共静态void main(字符串[]args){
ErrorReporting myError=新建ErrorReporting();
字节myByte=16;
myError.printByteArray(myByte);
}
公共无效打印字节数组(字节输入字节){
//打印出1或0
字节比较=-128;
对于(int x=0;x<8;x++){
如果((输入字节和比较)!=0){
系统输出打印(“1”);
}否则{
系统输出打印(“0”);
}
//系统输出打印(“比较:”+比较);
比较=(字节)(比较>>>1);
}
System.out.println(“:”+inputByte);
}
}

这篇文章有一些信息:

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

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

  • 在执行移位操作之前,所有参数首先提升为int,另请参见

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

  • 最简单的解决方案是对掩码使用
    int

    int comparison = 0x80;  // -128;
    
    理论上,您也可以使用一个字节作为掩码,但在应用移位运算符之前,您需要显式地将其转换为
    int
    ,同时丢弃符号位,如下所示:

    byte comparison = -128;
    ...
    comparison = (byte)( (((int) comparison) & 0xff) >>> 1);
    
    ((int)comparison)&0xff)
    假定字节实际上应该是“无符号”的,并将其转换为相应的“无符号”int值。然后,您可以应用移位运算符(
    >
    >
    无所谓,因为在任何情况下,我们都有一个正的
    int
    值)并将其转换回
    字节

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

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

  • 在执行移位操作之前,所有参数首先提升为int,另请参见

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

  • 最简单的解决方案是对掩码使用
    int

    int comparison = 0x80;  // -128;
    
    理论上,您也可以使用一个字节作为掩码,但在应用移位运算符之前,您需要显式地将其转换为
    int
    ,同时丢弃符号位,如下所示:

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

    ((int)comparison)&0xff)
    假定字节实际上应该是“无符号”的,并将其转换为相应的“无符号”int值。然后,您可以应用移位运算符(
    >
    >
    无所谓,因为我们在任何情况下都有一个正的
    int
    值)并将其转换回
    字节

    ,谢谢这项工作,我觉得Java自动升级到int有点烦人,这使得位运算符的行为不符合预期,我想知道他们为什么决定这样做。多亏了这项工作,我觉得Java自动升级到int有点烦人,这会使位智能操作符的行为不符合预期,我想知道他们为什么决定这样做。