Not registered yet?
Register now! It is easy and done in 1 minute and gives you access to special discounts and much more!
In Python console:
Why? Can someone explain this particular case to me in binary?
int(True) is 1.
and ~1 is:
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.
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.
>>> isinstance(True, int)
>>> True == 1
>>> True is 1 # they're still different objects
@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.
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).
Why is True=1 instead of -1, as it is in virtually every other language? (Sorry, PEP Index is currently out of service)
@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...
True == -1
True == 1
@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.
x & -1
x && 1
~True == -2 is not surprising if True means 1 and ~ means bitwise inversion...
~True == -2
~ does not mean "2s complement". ~ means "Bitwise Inversion"
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.
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
>>> not False
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), '08b')
>>> format(struct.pack('b', ~1), '08b')
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.
@GrijeshChauhan: For two's compliment, you could use struct.pack, as bin(integer) or format(integer, '08b') don't take signed integers into account.
@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.
What I mean 10 itself 2'complement then -ve?
Ok Understood... 10 can be three Thanks!
@GrijeshChauhan You can get the two's complement notation of both negative and positive numbers like this format(-2 % (1 << 32), "032b")
format(-2 % (1 << 32), "032b")
@thefourtheye: I'd use a bitmask: format(-2 & ((1 << 32) - 1), "032b")
format(-2 & ((1 << 32) - 1), "032b")
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.
@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.
@Bakuriu: But I think it hardly matters here; __invert__ is not implemented which is what would matter here.