Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does bitwise AND with byte in JAVA do this?

I'm messing around with bitwise operators, and I was trying to convert a negative byte to an unsigned 8 bit value, and this is what people suggested:

System.out.println(-20 & 0xFF); //bitwise AND on negative number and 255 

So, this works perfectly, and returns 236, but why? As far as I'm concerned:

00010100 //binary representation of -20
11111111 //binary representation of 0xFF or 255
--------
00010100 //it returns the same exact thing, so it's either -20 or 20

Why does it work? I think I've missed something pretty simple, but I can't seem to grasp it.

Also, if I do it with a positive number below 256, it returns the same number. I can't seem to understand what Java does with these numbers.

like image 373
ZimZim Avatar asked Dec 02 '25 10:12

ZimZim


2 Answers

The literals in Java are in the form of int. So when you say -20 & 0xFF, this is what happens:

  11111111 11111111 11111111 11101100 //-20 -ve nos are stored in 2's compliment form
& 00000000 00000000 00000000 11111111 // 0xFF 
  -------- -------- -------- --------
  00000000 00000000 00000000 11101100 // 236

Since the negetaive values are stored in 2's compliment form, you get the value 236.

When you perfrom 20 & 0xFF, this happens:

  00000000 00000000 00000000 00010100 // 20 -ve nos are stored in 2's compliment form
& 00000000 00000000 00000000 11111111 // 0xFF 
  -------- -------- -------- --------
  00000000 00000000 00000000 00010100 // 20
like image 93
Rahul Bobhate Avatar answered Dec 04 '25 23:12

Rahul Bobhate


A byte is a signed value held in 8 bits and may be in the range -128 to 127.

The left most bit is used as the sign bit.

System.out.println(-20 & 0xFF); has nothing to do with bytes, this is an int operation.

The binary representation of -20, as a byte is: 1110_1100

1110_1100 & 1111_1111 = 1110_1100

If you want unsigned, there's char to play with, but you're not going to be happy. Realistically, Java doesn't have unsigned.

Negatives are stored in '2s Complement' form, eg:

1111_1111 == -1

But why?

Under 2s complement to make a negative number, all the bits are flipped (1s complement) and 1 is added (making 2s complement - two operations)

So

 0000_0000 - Zero
-0000_0001 - minus one
 ---------
 1111_1110 - Ones complement - (this would be xor 1111_1111)
+0000_0001 - plus one - we're converting to 2s complement, not doing math
 ---------
 1111_1111 - -1 in 2s complement
like image 44
Ray Stojonic Avatar answered Dec 04 '25 23:12

Ray Stojonic