【问题标题】:Convert from 2 or 4 bytes to signed/unsigned short/int从 2 或 4 字节转换为有符号/无符号 short/int
【发布时间】:2012-05-29 17:00:54
【问题描述】:

我必须将字节转换为有符号/无符号整数或短整数。

以下方法正确吗?哪些已签名,哪些未签名?

字节顺序:LITTLE_ENDIAN

public static int convertTwoBytesToInt1(byte b1, byte b2) {
    return (int) ((b2 << 8) | (b1 & 0xFF));
}

VS.

public static int convertTwoBytesToInt2(byte b1, byte b2) {
    return (int) (( (b2 & 0xFF) << 8) | (b1 & 0xFF));
}

public static int  convertFourBytesToInt1(byte b1, byte b2, byte b3, byte b4){
    return (int) ((b4<<24)+(b3<<16)+(b2<<8)+b1);
}

VS.

public static int  convertFourBytesToInt2(byte b1, byte b2, byte b3, byte b4){
    return (int) (( (b4 & 0xFF) << 24) | ((b3 & 0xFF) << 16) | ((b2 & 0xFF) << 8) | (b1 & 0xFF));
}

对此转换表单感兴趣。谢谢!

【问题讨论】:

  • 我会使用 ByteBuffer,因为这样效率更高,您只需设置 .order(ByteOrder.LITTLE_ENDIAN)

标签: java int byte type-conversion


【解决方案1】:

每对的第一个方法(convertXXXToInt1())是有符号的,第二个(convertXXXToInt2())是无符号的。

但是,Java int 始终是有符号的,因此如果设置了 b4 的最高位,则 convertFourBytesToInt2() 的结果将为负数,即使这应该是“无符号”版本。

假设byte 的值,b2 为 -1,或十六进制的 0xFF。 &lt;&lt; 运算符将使其“提升”为值为 -1 或 0xFFFFFFFF 的 int 类型。移位8位后为0xFFFFFF00,移位24字节后为0xFF000000。

但是,如果您应用按位 &amp; 运算符,则高位将设置为零。这将丢弃符号信息。以下是这两个案例的第一步,更详细地制定了。

签名:

byte b2 = -1; // 0xFF
int i2 = b2; // 0xFFFFFFFF
int n = i2 << 8; // 0x0xFFFFFF00

无符号:

byte b2 = -1; // 0xFF
int i2 = b2 & 0xFF; // 0x000000FF
int n = i2 << 8; // 0x0000FF00

【讨论】:

  • 在 convertFourBytesToInt1 b1 没有 &0xff ......所以如果我不说它没有区别?还是有符号整数?
  • @blackwolf 实际上,它会有所不同,因为您将字节与 + 运算符组合在一起。我之前没有注意到,因为其他人使用| 运算符,这是位操作的首选。表达式应该是(int)((b4&lt;&lt;24) | ((b3 &amp; 0xFF)&lt;&lt;16) | ((b2 &amp; 0xFF)&lt;&lt;8) | (b1 &amp; 0xFF))
【解决方案2】:

4 字节无符号转换存在问题,因为它不适合 int。下面的例程可以正常工作。

public class IntegerConversion
{
  public static int convertTwoBytesToInt1 (byte b1, byte b2)      // signed
  {
    return (b2 << 8) | (b1 & 0xFF);
  }

  public static int convertFourBytesToInt1 (byte b1, byte b2, byte b3, byte b4)
  {
    return (b4 << 24) | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF);
  }

  public static int convertTwoBytesToInt2 (byte b1, byte b2)      // unsigned
  {
    return (b2 & 0xFF) << 8 | (b1 & 0xFF);
  }

  public static long convertFourBytesToInt2 (byte b1, byte b2, byte b3, byte b4)
  {
    return (long) (b4 & 0xFF) << 24 | (b3 & 0xFF) << 16 | (b2 & 0xFF) << 8 | (b1 & 0xFF);
  }

  public static void main (String[] args)
  {
    byte b1 = (byte) 0xFF;
    byte b2 = (byte) 0xFF;
    byte b3 = (byte) 0xFF;
    byte b4 = (byte) 0xFF;

    System.out.printf ("%,14d%n", convertTwoBytesToInt1 (b1, b2));
    System.out.printf ("%,14d%n", convertTwoBytesToInt2 (b1, b2));

    System.out.printf ("%,14d%n", convertFourBytesToInt1 (b1, b2, b3, b4));
    System.out.printf ("%,14d%n", convertFourBytesToInt2 (b1, b2, b3, b4));
  }
}

【讨论】:

  • b1 & 0xFF 是干什么用的?
  • @ScottF - 防止负值。
猜你喜欢
  • 2015-04-29
  • 2011-10-21
  • 2017-10-01
  • 1970-01-01
  • 2015-01-12
  • 1970-01-01
  • 2018-05-25
  • 2012-10-30
  • 2018-04-07
相关资源
最近更新 更多