By lukaszkups


2014-02-19 13:04:51 8 Comments

In Python console:

~True

Gives me:

-2

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

3 comments

@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 
         ↑          ↑ 
       Flip       Add 1

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.

Related Questions

Sponsored Content

25 Answered Questions

[SOLVED] Does Python have a ternary conditional operator?

40 Answered Questions

[SOLVED] What does the "yield" keyword do?

31 Answered Questions

[SOLVED] What does if __name__ == "__main__": do?

10 Answered Questions

[SOLVED] Does Python have a string 'contains' substring method?

16 Answered Questions

[SOLVED] What is a mixin, and why are they useful?

20 Answered Questions

[SOLVED] How to copy a dictionary and only edit the copy

11 Answered Questions

[SOLVED] Can someone explain __all__ in Python?

15 Answered Questions

[SOLVED] What is the meaning of a single and a double underscore before an object name?

12 Answered Questions

Sponsored Content