Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsigned Bytes in Java

Tags:

java

byte

Bytes in Java are signed by default. I see on other posts that a workaround to have unsigned bytes is something similar to that: int num = (int) bite & 0xFF

Could someone please explain to me why this works and converts a signed byte to an unsigned byte and then its respective integer? ANDing a byte with 11111111 results in the same byte - right?

like image 720
darksky Avatar asked Sep 01 '11 20:09

darksky


People also ask

What are negative bytes?

Problems arise when integers are type casted to bytes. This is a narrowing primitive conversion, for integers it works by copying the less significant bits. In this case, the eight less significant bits from the integer are copied to the byte. If the copied value is above 127 we end up with a negative byte value.

What is a byte in Java?

A byte in Java is 8 bits. It is a primitive data type, meaning it comes packaged with Java. Bytes can hold values from -128 to 127.

How big is a char in Java?

char: The char data type is a single 16-bit Unicode character. It has a minimum value of '\u0000' (or 0) and a maximum value of '\uffff' (or 65,535 inclusive).

Is Java long signed?

A long is always signed in Java, but nothing prevents you from viewing a long simply as 64 bits and interpret those bits as a value between 0 and 264.


2 Answers

A typecast has a higher precedence than the & operator. Therefore you're first casting to an int, then ANDing in order to mask out all the high-order bits that are set, including the "sign bit" of the two's complement notation which java uses, leaving you with just the positive value of the original byte. E.g.:

let byte x = 11111111 = -1
then (int) x = 11111111 11111111 11111111 11111111
and x & 0xFF = 00000000 00000000 00000000 11111111 = 255

and you've effectively removed the sign from the original byte.

like image 186
Ryan Stewart Avatar answered Sep 20 '22 01:09

Ryan Stewart


ANDing a byte with 11111111 results in the same byte - right?

Except you're ANDing with 00000000000000000000000011111111, because 0xFF is an int literal - there are no byte literals in Java. So what happens is that the byte is promoted to int (the typecast is unnecessary), has its sign extended (i.e. keeps the possibly negative value of the byte, but then the sign extension is reverted by ANDing it with all those zeroes. The result is an int that has as its least significant bits exactly the former byte and thus the value the byte would have had were it unsigned.

like image 41
Michael Borgwardt Avatar answered Sep 19 '22 01:09

Michael Borgwardt