位操作转换为整数

use*_*688 15 java

我有一些二进制操作不能像我期望的那样工作.我有字节数组,前两个字节有这些值:0x5和0xE0.我想将它们组合成一个应该是0x5E0的整数值.我试过做:

int val = (b[i]) << 8 | b[i+1];
Run Code Online (Sandbox Code Playgroud)

但是该值出现0xFFFFFFEE0并且第一个字节0x5正在丢失

我觉得这很容易?我究竟做错了什么?

Bre*_*ail 13

试试:int val = ((b[i] & 0xff) << 8) | (b[i + 1] & 0xff).不幸的是,字节用Java签名,因此如果设置了高位,则在转换为整数时它会被符号扩展.

  • @MarounMaroun我不知道我是否曾经发现签名字节有用,但我知道我犯了错误,因为它们是.我想我可以省略编辑:-). (8认同)
  • @maaartinus我不认为"没有收获"是准确的.如果你需要模2 ^ N的整数语义,那么你需要一个无符号类型.如果你需要一个更大的范围,一个永远不会消极的值而不使你的对象变大,那么你需要一个无符号类型.如果您不想要符号扩展,那么您需要一个无符号类型.C有混合有符号和无符号整数的规则,它们确实是理智的.当隐式转换符合您的要求时,无需进行转换. (3认同)

das*_*ght 5

问题是byte数据类型已签名.因此,b[i+1]在执行操作之前进行符号扩展0xFFFFFFE0.当它得到OR-ED与0x0500b[i]<<80x0500丢失.

您可以0xFF在执行操作之前通过AND-ing来解决此问题:

public static int toInt16(byte high, byte low) {
    int res = (high << 8);
    res |= (low & 0xFF);
    return res & 0xFFFF;
}
Run Code Online (Sandbox Code Playgroud)

演示.