marcinx27
marcinx27

Reputation: 253

Valid way to move bits in java

I'm working on an assignment for school and I'm getting strange output. So, I figured I should start checking some of my more basic methods before I get to the fancier ones. The question I have is this: would the method

public static short get16(byte a, byte b){  
    return (short)(a*Math.pow(2,8)+b)
}

return a short where the first 8 bits are byte a and the last 8 bits are byte b? I don't see why it wouldn't, since multiplying by 2^8 would be the same as left shifting 8 bits to the left. And adding the second byte would make up for the 8 0's achieved by multiplying by 2^8. Is this correct?

Upvotes: 1

Views: 1896

Answers (2)

Viliam Búr
Viliam Búr

Reputation: 2214

Some things you should know:

"Math.pow" is a floating-point function. Don't do integer calculation by calling floating-point functions and then rounding the result.

Java virtual machine is internally a 32-bit system. All "byte" and "short" mathematical expressions are internally evaluated as "int". Even an addition of two bytes goes internallly like this: 1) convert the bytes to ints, 2) add the ints, 3) convert the lower 8 bits to byte.

The correct way is:

return (short) ((a << 8) + (b & 255));

or

return (short) ((a << 8) | (b & 255));

When "byte" is converted to "int", the sign bit gets copied into the new bits. For example 0b01010101 becomes 0b00000000_00000000_00000000_01010101, because the first bit was 0, but 0b10101010 becomes 0b11111111_11111111_11111111_10101010.

Upvotes: 1

tmyklebu
tmyklebu

Reputation: 14215

I wouldn't recommend using Math.pow to compute 256. pow is notoriously hard to implement correctly; some extant implementations don't even get the exact cases right!

Also, bytes in Java are signed, so you probably want to say (a&255) and (b&255) rather than just a and b. Sign extension will ruin everything for you.

Upvotes: 2

Related Questions