Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitwise AND, Bitwise Inclusive OR question, in Java

I've a few lines of code within a project, that I can't see the value of...

buffer[i] = (currentByte & 0x7F) | (currentByte & 0x80);

It reads the filebuffer from a file, stored as bytes, and then transfers then to buffer[i] as shown, but I can't understand what the overall purpose is, any ideas?

Thanks

like image 954
Dave Avatar asked Feb 18 '09 12:02

Dave


2 Answers

As the other answers already stated, (currentByte & 0x7F) | (currentByte & 0x80) is equivalent to (currentByte & 0xFF). The JLS3 15.22.1 says this is promoted to an int:

When both operands of an operator &, ^, or | are of a type that is convertible (§5.1.8) to a primitive integral type, binary numeric promotion is first performed on the operands (§5.6.2). The type of the bitwise operator expression is the promoted type of the operands.

because JLS3 5.6.2 says that when currentByte has type byte and 0x7F is an int (and this is the case), then both operands are promoted to int.

Therefore, buffer will be an array of element type int or wider.

Now, by performing & 0xFF on an int, we effectively map the original byte range -128..127 into the unsigned range 0..255, an operation often used by java.io streams for example.

You can see this in action in the following code snippet. Note that to understand what is happening here, you have to know that Java stores integral types, except char, as 2's complement values.

byte b = -123;
int r = b;
System.out.println(r + "= " + Integer.toBinaryString(r));
int r2 = b & 0xFF;
System.out.println(r2 + "= " + Integer.toBinaryString(r2));

Finally, for a real-world example, check out the Javadoc and implementation of the read method of java.io.ByteArrayInputStream:

/**
 * Reads the next byte of data from this input stream. The value 
 * byte is returned as an <code>int</code> in the range 
 * <code>0</code> to <code>255</code>. If no byte is available 
 * because the end of the stream has been reached, the value 
 * <code>-1</code> is returned. 
 */
public synchronized int read() {
return (pos < count) ? (buf[pos++] & 0xff) : -1;
}
like image 131
eljenso Avatar answered Sep 20 '22 04:09

eljenso


 (currentByte & 0x7F) | (currentByte & 0x80)

is equivalent to

 currentByte & (0x7F | 0x80)

which equals

 currentByte & 0xFF

which is exactly the same as

 currentByte

Edit: I only looked at the right side of the assignment, and I still think the equivalance is true.

However, it seems like the code wants to cast the signed byte to a larger type while interpreting the byte as unsigned.

Is there an easier way to cast signed-byte to unsigned in java?

like image 38
Timbo Avatar answered Sep 18 '22 04:09

Timbo