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
-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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With