Я знаю, 42 - ответ на все, но как черт 42 результат этого?
int x = -(~'+'|0xAB^1337); //42
Я знаю, 42 - ответ на все, но как черт 42 результат этого?
int x = -(~'+'|0xAB^1337); //42
Чтобы понять, что происходит, вы должны посмотреть на двоичное представление значений в этом выражении. Но перед этим давайте посмотрим, как символы преобразуются в целые числа и какие побитовые операторы используются здесь.
'+' символ эквивалентен целочисленному значению 43 - вы можете проверить его, отбросив его до целого числа или используя Convert.ToInt32('+').
0xAB представляет собой шестнадцатеричный литерал, который представляет десятичное значение 171.
И последнее, что вы должны здесь понимать, это побитовые операторы:
~ побитовое NOT - оператор смотрит на двоичное представление значений выражения и выполняет побитовое отрицание на нем. Любая цифра, которая равна 1 в выражении, становится 0 в результате. Любая цифра, которая равна 0 в выражении, становится результатом 1.| побитовое ИЛИ - смотрит на двоичное представление значений двух выражений и выполняет побитовое ИЛИ на них. Каждый раз, когда любое из выражений имеет 1 в цифре, результат будет иметь 1 в этой цифре. В противном случае результат будет иметь 0 в этой цифре.^ побитовый XOR - смотрит на двоичное представление значений двух выражений и выполняет побитовое исключающее ИЛИ действие на них. Когда один и только один из выражений имеет 1 в цифре, результат имеет 1 в этой цифре. В противном случае результат будет иметь 0 в этой цифре.Теперь все выражения выглядят как -(NOT(43) OR (171 XOR 1337)). Перейдем к двоичному представлению этих чисел и операций:
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)
~'+', который является двоичным NOT на значении ascii '+' = > -440xAB^1337 (двоичный XOR) = > 1426-44|1426 (двоичный OR) = > -42-42 (арифметическое отрицание) = > 42Ну, пусть шаг за шагом будет декодироваться:
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
Преобразование в hex обеспечивает относительно простой подход к выполнению двоичных вычислений вручную:
'+' равен 0x2B или 00101011 в двоичном формате0x2B - 0xFFFFFFD4^ имеет более высокий приоритет, чем OR |, поэтому 0xAB сначала получает XOR-ed с 1337 (1337 - 0x539)000010101011 ^ 010100111001 = 010110010010, или 0x5920xFFFFFFD4 и 0x00000592 создает 0xFFFFFD60x0000002A, который равен 42 в десятичной форме.