-1

I was studying bitwise operators and they make sense until the unary ~one's complement is used with them. Can anyone explain to me how this works?

For example, these make sense however the rest of the computations aside from these do not:

1&~0 = 1   (~0 is 1 -> 1&1 = 1)
~0^~0 = 0  (~0 is 1 -> 1^1 = 0)
~1^0 = 1   (~1 is 0 -> 0^1 = 1)
~0&1 = 1   (~0 is 1 -> 1&1 = 1)
~0^~1 = 1  (~0 is 1, ~1 is 0 -> 1^0 = 1)
~1^~1 = 0  (~1 is 0 -> 0^0)

The rest of the results produced are negative(or a very large number if unsigned) or contradict the logic I am aware of. For example :

0&~1 = 0   (~1 = 0 therefor 0&0 should equal 0 but they equal 1)
~0&~1 = -2
~1|~0 = -1

etc. Anywhere you can point me to learn about this?

  • 1
    Could you better clarify to which type of variables ar you making this assignements? Hou are you printing them? Not with `%d`, I suppose.. – Roberto Caboni Oct 22 '19 at 08:13
  • Your examples appear to be for single-bit types only (with some typo's). Can you clarify what you're asking ? – Sander De Dycker Oct 22 '19 at 08:14
  • Those results are from printf like this: printf("%d", ~1|~0); –  Oct 22 '19 at 08:17
  • 1
    `%d` actually prints signed integers. Since with bitwise operations it happens to get most significant bit set in the result, you see negative values. In order to better understand the results of your operations, use `%08X`, printing numbers in decimal format (in case of UINT32. You will have `%04X` in case of UINT16 or `%02X` in case of UINT8). – Roberto Caboni Oct 22 '19 at 08:23

3 Answers3

1

They actually do make sense when you expand them out a little more. A few things to be aware of though:

  1. Bitwise AND yields a 1 only when both bits involved are 1. Otherwise, it yields 0. 1 & 1 = 1, 0 & anything = 0.

  2. Bitwise OR yields a 1 when any of the bits in that position are a 1, and 0 only if all bits in that position are 0. 1 | 0 = 1, 1 | 1 = 1, 0 | 0 = 0.

  3. Signed numbers are generally done as two's complement (though a processor does not have to do it that way!). Remember with two's complement, you invert and add 1 to get the magnitude when the highest bit position is a 1.

Assuming a 32-bit integer, you get these results:

 0 & ~1 = 0 & 0xFFFFFFFE = 0
~0 & ~1 = 0xFFFFFFFF & 0xFFFFFFFE = 0xFFFFFFFE (0x00000001 + 1) = -2
~1 | ~0 = 0xFFFFFFFE & 0xFFFFFFFF = 0xFFFFFFFF (0x00000000 + 1) = -1
John Szakmeister
  • 44,691
  • 9
  • 89
  • 79
0

~1 = 0 - No it's not. It's equal to -2. Let's take a eight bit two complement as example. The decimal number 1 has the representation 0000 0001. So ~1 will have 1111 1110 which is the two complement representation of -2.

klutt
  • 30,332
  • 17
  • 55
  • 95
0

0&~1 = 0 (~1 = 0 therefor 0&0 should equal 0 but they equal 1)

~1 equals -2. If you flip all the bits of a Two's Complement number, you multiply it by -1 and subtract 1 from the result. Regardless of that 0 has 0 for all the bits, so the result of & is going to be 0 anyway.

~0&~1 = -2

~0 has all bits set so ~0&~1 is just ~1. Which is -2.

~1|~0 = -1

~0 has all bits set, so the result of the | is ~0 (= -1) no matter what it is OR'd with.

Blaze
  • 16,736
  • 2
  • 25
  • 44