Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit operations converting to an integer

Tags:

java

I have some binary operations that are not working like I expect. I have byte array with the first 2 bytes having these values : 0x5, and 0xE0. I want to combine them into an integer value that should be 0x5E0. I tried doing :

int val = (b[i]) << 8 | b[i+1];

but the value is coming out 0xFFFFFFEE0 and the first byte 0x5 is getting lost

I thought this would be easy? What am I doing wrong?

like image 809
user3470688 Avatar asked Jul 13 '15 12:07

user3470688


People also ask

How do you turn a particular bit into a number?

The idea is to use bitwise << and | operators. Using expression “(1 << (k – 1))“, we get a number which has all bits unset, except the k'th bit. If we do bitwise | of this expression with n, we get a number which has all bits same as n except the k'th bit which is 1. Below is the implementation of above idea.

How do you convert a bit to a binary number?

Flipping a bit means toggling or inverting the current bit status. If the current bit is set i.e. 1 than invert it to 0 and vice versa. To flip all bits of a binary number you can run loop from 0 to size of the integer and flip individual bit at a time.

What does bitwise and do to integers?

The & (bitwise AND) in C or C++ takes two numbers as operands and does AND on every bit of two numbers. The result of AND is 1 only if both bits are 1. The | (bitwise OR) in C or C++ takes two numbers as operands and does OR on every bit of two numbers. The result of OR is 1 if any of the two bits is 1.

Which are bit operations?

Bitwise operations A bitwise operation operates on two-bit patterns of equal lengths by positionally matching their individual bits. For example, a logical AND (&) of each bit pair results in a 1 if both the first AND second bits are 1. If only one bit is a 1, the result is 0.


2 Answers

Try: int val = ((b[i] & 0xff) << 8) | (b[i + 1] & 0xff). Bytes are (unfortunately) signed in Java, so if the high bit is set, it gets sign-extended when converted to an integer.

like image 130
Brett Kail Avatar answered Sep 19 '22 13:09

Brett Kail


The problem is that byte data type is signed. Therefore, b[i+1] gets sign-extended before performing the operation, becoming 0xFFFFFFE0. When it gets OR-ed with 0x0500 from b[i]<<8, the 0x0500 gets lost.

You can fix this by AND-ing with 0xFF before performing the operation:

public static int toInt16(byte high, byte low) {
    int res = (high << 8);
    res |= (low & 0xFF);
    return res & 0xFFFF;
}

Demo.

like image 35
Sergey Kalinichenko Avatar answered Sep 17 '22 13:09

Sergey Kalinichenko