使用按位运算符将byte转换为int

时间:2015-02-18 09:29:17

标签: java int byte type-conversion bytebuffer

我在java中记录了一些代码。在我问我的问题之前,我会给你们一些背景信息。目标是读取和处理orsm file,这是一个包含十六进制代码的文件。

流程如下:使用FileChannel将somme字节读入ByteBuffer。填充缓冲区后,将每个字节转换为有符号整数。这是使用移位运算符完成的,如下所示:

return  (0x000000ff & (bb.get() << 0)) |
        (0x0000ff00 & (bb.get() << 8)) |
        (0x00ff0000 & (bb.get() << 16)) |
        (0xff000000 & (bb.get() << 24));

当bb离开Bytebuffer。我完全不知道这段代码的工作原理和原因,我搜索了一个出价,我找到的关闭事件是this旧的stackoverflow主题。我仍然没有任何线索,我想知道你是否可以帮助我找出这段代码被剪掉了?

2 个答案:

答案 0 :(得分:5)

这将从底层字节缓冲区中读取四个字节,并将它们拼接成一个int值,如下所示:

                        11111111 (first byte read)
                22222222         (second byte read)
        33333333                 (third byte read)
44444444                         (fourth byte read)

为实现这一点,对所有子结果执行按位OR运算,其中每个子结果在上图中准备一行。例如,第三行准备为

(0x00ff0000 & (bb.get() << 16))

执行以下操作:

  1. 读取字节:

    xxxxxxxx
    
  2. byte展开为int

    000000000000000000000000xxxxxxxx        
    
  3. 将位向左移16个插槽:

    00000000xxxxxxxx0000000000000000
    
  4. 最后,通过一个AND掩码推送它,它只允许x位通过。这是必需的,因为byte已签名,因此转换为int实际上可能会产生以下结果:

    111111111111111111111111xxxxxxxx
    
  5. 如果在移位之前执行了一个常量的AND-mask,代码可能会更简单:

    (bb.get() & 0xFF) << 16
    

    这实际上是Java在这些比特繁琐的操作中的标准习惯用法。


    虽然不是您提出的问题的答案,但使用提供的API肯定是首选(getInt方法)。你的字节顺序是小端,所以你只需要设置它:

    bb.order(ByteOrder.LITTLE_ENDIAN);
    

    作为参考,这是JDK对相同代码的实现:

    static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
        return (((b3       ) << 24) |
                ((b2 & 0xff) << 16) |
                ((b1 & 0xff) <<  8) |
                ((b0 & 0xff)      ));
    }
    

答案 1 :(得分:0)

基本上,它读取四个字节,每个字节为8位,并将它们组合成一个32位的整数。它通过将每个连续字节向左移动额外的8个位置来实现这一点,因此读取的第一个字节被放入整数(0-7)的最后一个(最低位)8位;下一个字节进入下一个8位(15-8)等等。

使用ByteBuffer的实际功能可以更容易地执行此操作:

bb.order(ByteOrder.LITTLE_ENDIAN); // Called once on the buffer
int intFromNextFourBytes = bb.getInt(); // Read the same value as your code.