The definition comes because of 2's complement representation of integers. So "really" ~n
is n
with all the bits flipped. But the result of flipping "all" the bits depends in a sense on how many bits n
has in the first place. CPython uses fixed-width integers internally but the language doesn't present them to the programmer, so the only definition that makes sense in general is the arithmetic one ~n = -n - 1
. But the motivation for that definition is flipping the bits of a fixed-width 2's complement integer.
1110 = ~2 can be easily visualized as -2
...1110
is not ~2
, it is -2
. ~2
is ...1101
because 2
is ...010
.
1101 = ~3 can't be visualized like this
...1101
is not ~3
, it is -3
. ~3
is ...1100
because 3
is ...011
.
The way I visualize this (when I visualize it at all -- as a mathematician by training I prefer not to consider specific numbers), is to know that in 2's complement, ...10...
is always a negated power of two. So ...10
is -2, ...100
is -4, etc.
Then in order to know what for example ...110110
is, it's ...110000
+ 110
, that is to say -16
+ 6
, which is -10
.
Of course ...110110
is also (by bit flipping) ~1001
, that is to say ~9
, which by the formula is -9-1
, which is also -10
. So the system works ;-)