Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

convert 3 bytes to int in java

  1. I want to convert bytes to int in Java. I want to assume bytes to be unsigned bytes. Suppose if

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

    r should be 255 not -1 in decimal.

  2. Then I want to create int value from 3 bytes. Suppose if

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

    Then r should be 0x000FFFFF. Byte b1 will be placed at higher 3rd position and byte b3 will be placed at lower 1st position in int value. Also my b1 will range from 0x00 to 0x0F and other bytes will be from 0x00 to 0xFF, assuming unsigned nature of bytes. If byte b1 is greater than 0x0F, I will extract only lowermost 4 bits. In short I want to extract int from 3 bytes but using only 20 bits of 3 bytes. (total 16 bits from b2 and b3, and 4 lowermost bits from b1). int r must be positive as we are creating from 3 bytes and assuming unsigned nature of bytes.

like image 599
nullptr Avatar asked Oct 31 '12 09:10

nullptr


People also ask

Can we convert byte to int in Java?

The intValue() method of Byte class is a built in method in Java which is used to return the value of this Byte object as int.

How many bytes is an int?

The int and unsigned int types have a size of four bytes.

Why is int 4 bytes?

So the reason why you are seeing an int as 4 bytes (32 bits), is because the code is compiled to be executed efficiently by a 32-bit CPU. If the same code were compiled for a 16-bit CPU the int may be 16 bits, and on a 64-bit CPU it may be 64 bits.

Why is Java byte 128?

This is because we have to represent the number 0, so inclusively 0-127 is the other 128 possibilities of our range. If we were only allowing positive values, such as an unsigned byte where negative numbers aren't possible, the range would be 0-255, since these are 256 different values (including the 0).


3 Answers

You have to be careful with the sign-extension here - unfortunately, bytes are signed in Java (as far as I know, this has caused nothing but grief).

So you have to do a bit of masking.

int r = (b3 & 0xFF) | ((b2 & 0xFF) << 8) | ((b1 & 0x0F) << 16);
like image 124
harold Avatar answered Nov 09 '22 10:11

harold


I would assume you want unsigned byte values

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

Every byte needs to be masked and shifted to the right bits.

like image 28
Peter Lawrey Avatar answered Nov 09 '22 08:11

Peter Lawrey


This is pretty easy with bitshifting operators, and binary AND. You want to use only the lower 4 bits of b1, that's exactly what b1 & 0x0F does. All the rest is shifting the bits to various positions

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

EDIT as @harold pointed out, the former solution (without the 0xFF mask on the lower bytes) would have led to anomalies due to sign extension...

EDIT2 gosh, I always get punched in the face by operator precedence when dealing with these...

Recommended reading:

  • Sign extension in Java
  • Suppressing sign extension when upcasting or shifting in Java
  • Operator Precedence in Java
like image 24
ppeterka Avatar answered Nov 09 '22 09:11

ppeterka