Why Does “~True” Result in -2 in Python?

Maroun Maroun
2 min readFeb 26, 2021
Image credit: plotplot | Shutterstock.com

In this short article, I’ll try to explain why we get the following:

$ python3
Python 3.9.0 (default, Dec 6 2020, 18:02:34)
[Clang 12.0.0 (clang-1200.0.32.27)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> ~True
-2

Think about bool, you'll find that it is numeric in nature - It can hold two values, "True" and "False", and they are just ‘customized’ versions of the integers 1 and 0, that only print themselves differently.

So now it’s clear that bool is actually a subclass of int:

>>> type(True)
<class 'bool'>
>>> isinstance(True, int)
True
>>> True == 1
True
>>> True is 1 # they're still different objects
False

Having that said, ~True evaluates to:

~True == ~int(True) == ~1 == -2

The ~ operator is for bitwise inversion — it simply flips bits. So:

1  = 00000001
~1 = 11111110

which is -2 in two’s complement. The ‘algorithm’ below describes how to get a number’s two’s complement:

  • Flip all the bits
  • add 1 to the resulting number
  • interpret the result as a binary representation of the magnitude
  • to determine the sign — if the original number begins with ‘1’, it’s negative, positive otherwise
11111110 → 00000001 → 00000010 
↑ ↑
Flip Add 1

“00000010” in binary is 2, but since the original number is “11111110”, which its MSB is “1”, the sign is determined as negative, and the final result would be “-2”.

I hope that was clear :)

--

--