Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does negating a value change the result when XORing it with 1? [duplicate]

I know the working of XOR,

Console.WriteLine(1^1);  // returns 0

results to

00000001
00000001 
--------
00000000 

but how does this return 2?

Console.WriteLine(-(-1^1)); // returns 2
like image 957
Toshi Avatar asked May 05 '17 07:05

Toshi


2 Answers

-1 is stored as a value with all bits set to 1. If we are staying on your 8 bits example, -1 would then be equal to 11111111. So -1^1 gives the following:

11111111
00000001 
--------
11111110

Which is equal to -2. When you invert it with another minus, you get 2.

Negative numbers are stored in a way we call two's complement of the number. If you want to compute it quickly in your head, you can just flip all the bits of the positive equivalent of your number, and add one to it. So for -1:

 1: 00000001
    --------
    11111110
   +       1
    --------
-1: 11111111

Explaining why -1 is stored as 11111111.

If you want to understand two's complement a bit more, this question may also help you.

like image 54
Izukani Avatar answered Oct 13 '22 20:10

Izukani


This expression is interpreted by the compiler as:

-((-1)^1)

which is: - ((11111111) XOR (00000001)) = -(11111110) = - (-2) = 2

To understand why the compiler chooses -((-1)^1) instead of -(-(1^1)), take a look at this article about C# operators precedence. The most relevant piece is that the unary - operator (the bolded one: -( - 1^1) ) has a higer precedence than the XOR operator ^. Therefore the negation happens before XOR, and we end up with -((-1)^1).

I am using 8 bits per integer here. Normally you should expect 32 or 64 bits per number, but in this case it is irrelevant;


To better understand why 11111111 is -1, and 11111110 is -2, read more about two's complement - https://en.wikipedia.org/wiki/Two%27s_complement. In short, you treat all the bits apart from the left-most, as consecutive powers of 2. The leftmost bit is treated as the next-power, but negative.

Example:

10001100 = 1 * (-(2^7)) + 0 * 2^6 + 0 * 2^5 + 0 * 2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
like image 26
Michał Avatar answered Oct 13 '22 21:10

Michał