I know, 42 is the answer to everything but how the heck is 42
the result of this?
int x = -(~'+'|0xAB^1337); //42
I know, 42 is the answer to everything but how the heck is 42
the result of this?
int x = -(~'+'|0xAB^1337); //42
To understand what happens, you should look at the binary representation of values in this expression. But before that let's look how characters are converted to integers and what bitwise operators are used here.
'+'
character is equivalent to integer value 43
- you can check it by casting it to the integer, or by using Convert.ToInt32('+')
.
0xAB
is a hexadecimal literal, which represents decimal value 171
.
And the last thing you should understand here is bitwise operators:
~
bitwise NOT - operator looks at the binary representation of the values of the expression and does a bitwise negation operation on it. Any digit that is a 1 in the expression becomes a 0 in the result. Any digit that is a 0 in the expression becomes a 1 in the result.|
bitwise OR - looks at the binary representation of the values of two expressions and does a bitwise OR operation on them. Any time either of the expressions has a 1 in a digit, the result will have a 1 in that digit. Otherwise, the result will have a 0 in that digit.^
bitwise XOR - looks at the binary representation of the values of two expressions and does a bitwise exclusive OR operation on them. When one, and only one, of the expressions has a 1 in a digit, the result has a 1 in that digit. Otherwise, the result has a 0 in that digit.Now all expression looks like -(NOT(43) OR (171 XOR 1337))
. Let's move to binary representation of these numbers and operations:
Binary | Decimal | Comments
00000000000000000000000000101011 | 43 | '+'
11111111111111111111111111010100 | -44 | NOT 43 // bits are inverted
00000000000000000000000010101011 | 171 | 0xAB
00000000000000000000010100111001 | 1337 |
00000000000000000000010110010010 | 1426 | 171 XOR 1337 // different bits produce 1
11111111111111111111111111010100 | -44 | NOT 43
00000000000000000000010110010010 | 1426 | 171 XOR 1337
11111111111111111111111111010110 | -42 | -44 OR 1426 // 0 only if both bits are 0
00000000000000000000000000101010 | 42 | -(-42)
~'+'
, which is binary NOT on the ascii value of '+'
=> -440xAB^1337
(binary XOR) => 1426-44|1426
(binary OR) => -42-42
(arithmetical negation) => 42Well, let's decode step by step:
int x = -(~'+'|0xAB^1337) ==
-((~'+') | 0xAB ^ 1337) == // '+' is char with ASCII code 43
-((~43)) | 0xAB ^ 1337) ==
-(0xFFFFFFD4 | 0xAB ^ 0x539) ==
-(0xFFFFFFD6) == // negation is binary complement + 1
(~0xFFFFFFD6 + 1) ==
42
Converting to hex provides a relatively easy approach to doing binary computations manually:
'+'
is 0x2B, or 00101011
in binary0x2B
is 0xFFFFFFD4
^
has higher priority than OR |
, so 0xAB
gets XOR-ed with 1337 first (1337 is 0x539
)000010101011 ^ 010100111001 = 010110010010
, or 0x592
0xFFFFFFD4
and 0x00000592
produces 0xFFFFFD6
0x0000002A
, which is equal to 42 in decimal.