3 and 5:
0011 0101 ----- AND 0001 == 1
3 | 5:
0011 0101 ----- OR 0111 == 7
Denial in Java is defined as two complementary denials (which is extremely common). So -x = ~x + 1 = ~(x - 1)
.
8 and -8:
00001000 //8 11111000 //-8 -------- AND 00001000 // 8
Using the last definition of negation, -1 first takes all the rightmost zeros (if any), setting them as he goes, until he reaches 1, which he discards, everything that is left of him remains unchanged. Then the complement restores the rightmost zeros and the rightmost one (all of them are effectively supplemented by -1) and supplements everything to the left of the rightmost one:
00001000 // 8 00000111 // 8 - 1 = 7 11111000 // -8
Please note that -8 is only 11111000 if you are working with 8-bit numbers. If you had more bits, there would be more than 1 on the left. If you have only 4 bits, you are faced with some kind of problem, because -8 got the same representation as 8, and therefore -8 (in 4-bit math) a number, which is its own negative (for example, zero) .
Actually, 8 is not a good example, because it is too simple. Let do 100 & -100
(one hundred, not 4):
01100100 // 100 01100011 // 99 10011100 // -100
Now with 100:
01100100 // 100 10011100 // -100 -------- AND 00000100 // 4
In the general case, x & -x
isolates the rightmost 1. None of the rightmost zeros, not the rightmost 1, is independent of negation, and therefore only for that part of the number it looks like you are doing x & x
(which of course, x
) . The upper part, to the left of the rightmost one, is supplemented, so wherever you have 1, it becomes 0, and wherever you have 1, it becomes 0. 0 & 1 = 0
, so it gives 0 everywhere.