23

I know, 42 is the answer to everything but how the heck is 42 the result of this?

int x = -(~'+'|0xAB^1337); //42
brianpck
  • 8,084
  • 1
  • 22
  • 33
Toshi
  • 2,532
  • 4
  • 17
  • 45
  • 22
    Isn't it obvious? That's my usual way to initialize ints that are 42 ;) – Tim Schmelter Jun 02 '17 at 12:24
  • 4
    @TimSchmelter And what about initializing 43? – MakePeaceGreatAgain Jun 02 '17 at 12:25
  • 14
    @HimBromBeere `int x = -(~'+'|0xAB^1337); ++x;` Simplicity itself. – ashbygeek Jun 02 '17 at 12:28
  • @ashbygeek you little cheater :> – pitersmx Jun 02 '17 at 12:29
  • 6
    Funny question, but doesn´t show any own affords to solve it. In particular: how is this useful to *anyone*? – MakePeaceGreatAgain Jun 02 '17 at 12:33
  • @HimBromBeere: earlier we had a close vote reason: ["too localized"](https://meta.stackexchange.com/questions/4818/what-questions-should-be-closed-with-reason-too-localized) – Tim Schmelter Jun 02 '17 at 12:37
  • 2
    `+'+'` can be used for 43, but who would ever need anything other than 42 :] – Slai Jun 02 '17 at 12:39
  • @TimSchmelter We still have a chance to downvote unuseful questions without any own affords. – MakePeaceGreatAgain Jun 02 '17 at 12:40
  • @HimBromBeere: what can you try here if you have no idea? Anyway, it's not the lack of own effort but the fact that this question will never ever help someone else, so it's a perfect "too localized" example. – Tim Schmelter Jun 02 '17 at 12:42
  • 3
    @TimSchmelter Just like just about every other "why is my code doing this" question, you can easily break this down to figure it out. The first step is knowing what every operator does, then figuring out in which order things happen, then just evaluating it step by step. Maybe I've just been programming too long or I'm just very logical, but I honestly can't see how any given person can't have at least *some* idea of where to start with decoding this. – Bernhard Barker Jun 02 '17 at 15:58
  • @TimSchmelter Of course there are a few complex things actually going on here that one might not be able to figure out, but the code as a whole should still be broken down and the question should focus on one such thing (good point me - this question is "too broad"), which might be an actual useful question (although then it probably won't draw upvotes due to "cuteness"). – Bernhard Barker Jun 02 '17 at 16:13
  • 1
    @Dukeling c# is a high level language, bitwise operators and hexadecimal literals are not part of some educations using the language. If you don't know what those are I'm curious how one can search? – Thor Jun 02 '17 at 17:01
  • 3
    @Thor As I mentioned above, one should break it down and ask about an individual thing one doesn't understand, not just dump some code (even if it's just a line) and ask for an explanation. But really, [these things](https://stackoverflow.com/questions/8186965/what-do-numbers-using-0x-notation-mean) [are pretty easy](https://stackoverflow.com/questions/3735623/what-are-the-and-operators-used-for) [to Google](https://stackoverflow.com/questions/7986978/what-does-the-tilde-mean-in-an-expression) (those are all potential duplicates). – Bernhard Barker Jun 02 '17 at 17:09
  • If your education in the C# language didn't cover bitwise operators or hexadecimal literals, and you paid for that education, then you should apply for a refund. You should have at least passing familiarity with what these operators *do*, since they are a fundamental part of the language, and that should be enough for you to look up how bitwise arithmetic works in a particular case. Arming yourself with the Windows (or other OS's) calculator in "programmer" mode, which shows manipulations of individual bits, should be sufficient to arrive at an answer with a few moments' attention. – Cody Gray - on strike Jun 03 '17 at 11:28

4 Answers4

29

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)

Try online.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 2
    I think this is the first answer about bitwise operators that I actually understand all the way through! – dj18 Jun 02 '17 at 15:05
14
  1. Evaluate ~'+', which is binary NOT on the ascii value of '+' => -44
  2. Evaluate 0xAB^1337 (binary XOR) => 1426
  3. Evaluate -44|1426 (binary OR) => -42
  4. Evaluate -42 (arithmetical negation) => 42
adjan
  • 13,371
  • 2
  • 31
  • 48
8

Well, 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
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
3

Converting to hex provides a relatively easy approach to doing binary computations manually:

  • Code for '+' is 0x2B, or 00101011 in binary
  • Inverted bit pattern for 0x2B is 0xFFFFFFD4
  • XOR ^ has higher priority than OR |, so 0xAB gets XOR-ed with 1337 first (1337 is 0x539)
  • The result of XOR is 000010101011 ^ 010100111001 = 010110010010, or 0x592
  • Bitwise OR of 0xFFFFFFD4 and 0x00000592 produces 0xFFFFFD6
  • Negating this produces 0x0000002A, which is equal to 42 in decimal.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523