在java中将3个字节转换为int

时间:2012-10-31 09:23:08

标签: java bit-manipulation

  1. 我想在Java中将字节转换为int。 我想假设字节是无符号字节。 假设

    byte a = (byte)0xFF;
    
    int r = (some operation on byte a);
    

    r应该是255而不是十进制的-1。

  2. 然后我想从3个字节创建int值。 假设

    byte b1 = (byte)0x0F;
    
    byte b2 = (byte)0xFF;
    
    byte b3 = (byte)0xFF;
    
    int r = (some operation in bytes b1, b2 and b3);
    

    然后r应为0x000FFFFF。字节b1将位于较高的第3位置,字节b3将位于较低的第1位置的int值。假设无符号的字节性质,我的b1将从0x00到0x0F,其他字节将从0x000xFF。如果字节b1大于0x0F,我将只提取最低4位。简而言之,我想从3个字节中提取int,但只使用20个3字节。 (来自b2和b3的总共16位,以及来自b1的4位最低位)。 int r必须是正数,因为我们从3个字节创建并假设字节的无符号性质。

5 个答案:

答案 0 :(得分:3)

你必须小心这里的符号扩展 - 不幸的是,字节是用Java签名的(据我所知,这只会引起悲伤)。

所以你必须做一些掩饰。

int r = (b3 & 0xFF) | ((b2 & 0xFF) << 8) | ((b1 & 0x0F) << 16);

答案 1 :(得分:3)

我认为你想要无符号字节值

int r = ((b1 & 0xF) << 16) | ((b2 & 0xFF) << 8) | (b3 & 0xFF);

每个字节都需要被屏蔽并移位到正确的位。

答案 2 :(得分:2)

使用位移操作符和二进制AND非常简单。您只想使用b1的低4位,这正是b1 & 0x0F所做的。所有其余的都是将位移到不同的位置

int r = ( (b1 & 0x0F) << 16) + ((b2 & 0xFF) << 8) + (b3 & 0xFF)
@harold指出,

编辑,前一个解决方案(在较低字节上没有0xFF掩码)会因符号扩展而导致异常......

EDIT2 天哪,在处理这些问题时,我总是被运营商的优先权击穿...

推荐阅读:

答案 3 :(得分:1)

这是“仅限移位”版本:

int r = ((b1 << 28) >>> 12) | (b2 << 8) | b3;

从前4位向左移动28位斩波,然后右移12使其返回到左移16位。

我测试了这段代码并且有效:)

答案 4 :(得分:1)

我比较了一些答案,因为我很好奇哪一个是最快的。

似乎Bohemian的方法是最快的,但我无法解释为什么它在第一次运行时慢了11%。

PS。:我没有检查答案的正确性。

这里是代码:

public class Test
{

  public static void main(String[] args)
  {
    final int RUNS = 10;
    final int TRIPLE = 3;
    final int N = 100000000;

    byte[] bytes = new byte[TRIPLE * 32768]; // 96 kB

    Random r = new Random();
    r.nextBytes(bytes);

    List<ByteConvertTester> testers = Arrays.asList(new Harold(), new Bohemian(), new Ppeterka());

    for (int i = 0; i < RUNS; i++)
    {
      System.out.println("RUN#" + i);
      System.out.println("----------------------");
      Integer compare = null;
      for (ByteConvertTester tester : testers)
      {
        System.out.println(tester.getClass().getSimpleName());
        long time = testAndMeasure(tester, bytes, N);
        System.out.print("time (in ms): " + time);
        if (compare != null) {
          System.out.println(" SpeedUp%: " + (double) ((int) (10000 * (1.0d - (double) time / compare))) / 100);
        } else {
          compare = (int) time;
          System.out.println();
        }
      }
      System.out.println("----------------------");
    }
  }

  private static long testAndMeasure(ByteConvertTester bct, byte[] bytes, int loops)
  {
    Calendar start = Calendar.getInstance();
    int r;
    for (int i = 0; i < loops; i += 3)
      r = bct.test(bytes[i % bytes.length], bytes[(i + 1) % bytes.length], bytes[(i + 2) % bytes.length]);

    Calendar end = Calendar.getInstance();
    long time = (end.getTimeInMillis() - start.getTimeInMillis());
    return time;
  }
}

interface ByteConvertTester
{
  public int test(byte msb, byte mid, byte lsb);
}

class Harold implements ByteConvertTester
{
  @Override
  public int test(byte msb, byte mid, byte lsb)
  {
    return (lsb & 0xFF) | ((mid & 0xFF) << 8) | ((msb & 0x0F) << 16);
  }
}

class Bohemian implements ByteConvertTester
{
  @Override
  public int test(byte msb, byte mid, byte lsb)
  {
    return ((msb << 28) >>> 12) | (mid << 8) | lsb;
  }
}

class Ppeterka implements ByteConvertTester
{

  @Override
  public int test(byte msb, byte mid, byte lsb)
  {
    return ((msb & 0x0F) << 16) + ((mid & 0xFF) << 8) + (lsb & 0xFF);
  }
}

<强>输出

RUN#0
----------------------
Harold
time (in ms): 489
Bohemian
time (in ms): 547 SpeedUp%: -11.86
Ppeterka
time (in ms): 479 SpeedUp%: 2.04
----------------------
RUN#1
----------------------
Harold
time (in ms): 531
Bohemian
time (in ms): 521 SpeedUp%: 1.88
Ppeterka
time (in ms): 537 SpeedUp%: -1.12
----------------------
RUN#2
----------------------
Harold
time (in ms): 531
Bohemian
time (in ms): 539 SpeedUp%: -1.5
Ppeterka
time (in ms): 532 SpeedUp%: -0.18
----------------------
RUN#3
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 519 SpeedUp%: 1.89
Ppeterka
time (in ms): 531 SpeedUp%: -0.37
----------------------
RUN#4
----------------------
Harold
time (in ms): 527
Bohemian
time (in ms): 519 SpeedUp%: 1.51
Ppeterka
time (in ms): 530 SpeedUp%: -0.56
----------------------
RUN#5
----------------------
Harold
time (in ms): 528
Bohemian
time (in ms): 519 SpeedUp%: 1.7
Ppeterka
time (in ms): 532 SpeedUp%: -0.75
----------------------
RUN#6
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 520 SpeedUp%: 1.7
Ppeterka
time (in ms): 532 SpeedUp%: -0.56
----------------------
RUN#7
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 520 SpeedUp%: 1.7
Ppeterka
time (in ms): 533 SpeedUp%: -0.75
----------------------
RUN#8
----------------------
Harold
time (in ms): 530
Bohemian
time (in ms): 521 SpeedUp%: 1.69
Ppeterka
time (in ms): 532 SpeedUp%: -0.37
----------------------
RUN#9
----------------------
Harold
time (in ms): 529
Bohemian
time (in ms): 527 SpeedUp%: 0.37
Ppeterka
time (in ms): 530 SpeedUp%: -0.18
----------------------