[SOLVED] Why does ~True result in -2?

In Python console:

``````~True
``````

Gives me:

``````-2
``````

Why? Can someone explain this particular case to me in binary?

@Maroun 2014-02-19 13:09:39

`int(True)` is `1`.

`1` is:

``````00000001
``````

and `~1` is:

``````11111110
``````

Which is `-2` in Two's complement1

1 Flip all the bits, add 1 to the resulting number and interpret the result as a binary representation of the magnitude and add a negative sign (since the number begins with 1):

``````11111110 → 00000001 → 00000010
↑          ↑
``````

Which is 2, but the sign is negative since the MSB is 1.

Worth mentioning:

Think about `bool`, you'll find that it's numeric in nature - It has two values, `True` and `False`, and they are just "customized" versions of the integers 1 and 0 that only print themselves differently. They are subclasses of the integer type `int`.

So they behave exactly as 1 and 0, except that `bool` redefines `str` and `repr` to display them differently.

``````>>> type(True)
<class 'bool'>
>>> isinstance(True, int)
True

>>> True == 1
True
>>> True is 1  # they're still different objects
False
``````

@Grijesh Chauhan 2014-02-19 13:35:32

@ofcapl Just wanted to say: Although `int('1')` is also `1` but `~'1'` be a typeerror exception whereas `~True` is not this is because `bool` is a subclass of `int` @ Martijn added this information in his answer.

@Patrick M 2014-02-19 15:53:13

For the record, @ofcapl, this answer shows the binary arithmetic interpretation of what's going on, not the actual bytecode (which would be some sort of intermediate or operation level code compiled from the source).

@Flávio Etrusco 2014-02-19 23:17:49

Why is True=1 instead of -1, as it is in virtually every other language? (Sorry, PEP Index is currently out of service)

@l4mpi 2014-02-20 09:19:17

@etrusco what languages are you talking about? I know exactly 0 where `True == -1`, and I know many where one could say that `True == 1`...

@Quuxplusone 2014-02-20 19:56:22

@etrusco @l4mpi Some old-school BASICs use `-1` for TRUE; it has the nice property that the bitwise AND and OR operators work for logical AND and OR as well (`x & -1` is non-zero in the same cases that `x && 1` is non-zero in C), as long as you don't care about short-circuiting. However, as far as I know, no mainstream language has ever used `-1` for TRUE.

@Nicholas Carey 2014-02-20 20:27:33

Formal logic defines `truth` as univalued; with all that is not `true` being `false`. All programming languages that I'm aware of turn formal logic on its head, defining `false` as univalued (0) and all that is not false being `true`). For instance C#, though Javascript is something of an outlier, having multiple flavors of truthiness and multiple flavors of falsiness.

@Wolf 2014-02-20 08:47:19

`~True == -2` is not surprising if `True` means `1` and `~` means bitwise inversion...

...provided that

• `True` can be treated as an integer and
• integers are represented in Two's complement

Edits:

• fixed the mixing between integer representation and bitwise inversion operator
• applied another polishing (the shorter the message, the more work needed)

@McKay 2014-02-20 14:18:16

`~` does not mean "2s complement". `~` means "Bitwise Inversion"

@McKay 2014-02-20 14:27:05

The phrase "Ones' complement" doesn't really refer to an operation, as much as it refers to a system of storing integers in bits. A system that isn't actually used in a computer system.

@Martijn Pieters 2014-02-19 13:07:21

The Python `bool` type is a subclass of `int` (for historical reasons; booleans were only added in Python 2.3).

Since `int(True)` is `1`, `~True` is `~1` is `-2`.

See PEP 285 for why `bool` is a subclass of `int`.

If you wanted the boolean inverse, use `not`:

``````>>> not True
False
>>> not False
True
``````

If you wanted to know why `~1` is `-2`, it's because you are inverting all bits in a signed integer; `00000001` becomes `1111110` which in a signed integer is a negative number, see Two's complement:

``````>>> # Python 3
...
>>> import struct
>>> format(struct.pack('b', 1)[0], '08b')
'00000001'
>>> format(struct.pack('b', ~1)[0], '08b')
'11111110'
``````

where the initial `1` bit means the value is negative, and the rest of the bits encode the inverse of the positive number minus one.

@Martijn Pieters 2014-02-19 13:16:14

@GrijeshChauhan: For two's compliment, you could use `struct.pack`, as `bin(integer)` or `format(integer, '08b')` don't take signed integers into account.

@Grijesh Chauhan 2014-02-19 13:19:36

@thefourtheye , MartijnPieters I Tried But it is confusing e.g. `bin(~True)`, `bin(-2)`, `bin(~1)` all gives `'-0b10'` If `-2` representation is `10` then why `-` sign.

@Grijesh Chauhan 2014-02-19 13:21:33

What I mean `10` itself 2'complement then -ve?

@Grijesh Chauhan 2014-02-19 13:25:50

Ok Understood... 10 can be three Thanks!

@thefourtheye 2014-02-19 13:26:29

@GrijeshChauhan You can get the two's complement notation of both negative and positive numbers like this `format(-2 % (1 << 32), "032b")`

@Martijn Pieters 2014-02-19 13:28:37

@thefourtheye: I'd use a bitmask: `format(-2 & ((1 << 32) - 1), "032b")`

@Bakuriu 2014-02-19 21:56:38

There's a small step missing in your explanation (and in the other answer as well). The fact that `bool` subclasses `int` doesn't imply that `~True` must be `-2`. The fact that `bool` is a subclass of `int` that overrides only `&`, `|` and `^` does, which might not be obvious.

@Martijn Pieters 2014-02-19 22:40:56

@Bakuriu: Ah, I'll have to take that back; `bool` does override those methods, to make sure to call `super(bool, self).__<operator>__(other)` if either `self` or `other` is not a `bool` instance.

@Martijn Pieters 2014-02-19 22:43:32

@Bakuriu: But I think it hardly matters here; `__invert__` is not implemented which is what would matter here.