2012-10-31 68 views
8
  1. 我想在Java中将字节转换为int。 我想假设字节为无符号字节。 假设如果在java中将3个字节转换为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将被放置在较高的第三位置,而字节b3将被放置在较低的第一位置。假设字节的无符号性,我的b1的范围从0x00到0x0F,其他字节将从0x000xFF。如果字节b1大于0x0F,我将只提取最低4位。简而言之,我想从3个字节中提取int,但只使用3个字节的20位。 (来自b2和b3的总共16个比特,以及来自b1的最低4个比特)。 int r必须是正数,因为我们从3个字节创建并假定字节的无符号性质。

回答

3

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

所以你必须做一些掩蔽。

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

感谢哈罗德,我得到正确的答案与您的解决方案。请解释为什么逆序,我的意思是从上面的b1开始,它给我32640,这就是@ppeterka发布的解决方案。 – UDPLover

+0

@ user1508907顺序并不重要,但是ppeterka的回答可能会比'<<'更强烈地用'+'绑定。 – harold

+0

是的,我明白了。 ppeteka不使用括号。由于运营商的优先规则,解决方案陷入困境 – UDPLover

1

这里的一个“仅移动”版本:

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

左移28位扒关闭顶部4位,那么右移12带来回净16位左移位。

我测试此代码,它的工作原理:)

+0

你能解释一下你所期望的过度转移来实现呢? –

+0

哇,移动36位,砍掉顶部4位:) Eeeeevil :)我喜欢这样!很高兴每天都能学到东西! – ppeterka

+0

这将签署延长第20位。如果你不希望你可以使用'>>>' –

2

这是很容易与bitshifting运营商,以及二进制和。你只想使用b1的低4位,这正是b1 & 0x0F所做的。所有剩下的就是移位比特到各种位置

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

EDIT作为@harold指出的那样,前一种溶液(不在下字节0xFF的掩模)会导致由于符号扩展异常.. 。

EDIT2天哪,我总是在脸上的运算符优先级与这些打交道时,打孔......

推荐阅读:

+0

废话,非常真实!马上更新 – ppeterka

+0

我上面试过 - public class main { public static void main(String [ ]参数){ 字节B1 =(字节)为0x0F; 字节B2 =(字节)0xff的; 字节B3 =(字节)0xff的; INT R =(B1&为0x0F << 16)+(B2&0xFF的)<< 8 +(b3&0xFF); //打印 - r:32640 //我要r:1048575 System.out.println(“r:”+ r); } } 它给我32640,我想1048575 – UDPLover

+0

谢谢,但你的解决方案是错误的。当我从b3而不是b1开始时,它按照哈罗德给我正确的答案。使用你的解决方案给我32640,我想要1048575. – UDPLover

3

我会假设你想无符号字节值

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

每个字节需要被掩盖和右移位。

+1

这是正确的解决方案。谢谢 – UDPLover

0

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

似乎波希米亚的方法是最快的,但我不能解释为什么它在第一次运行中慢了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 
----------------------