为什么〜True导致-2?


132

在Python控制台中:

~True

给我:

-2

为什么?有人可以用二进制给我解释这个特殊情况吗?


22
因为~1-2,请尝试:True == 1
Grijesh Chauhan 2014年

15
准确地说:“ True is 1” 不是真的,但是True == 1
2014年

3
您是否真的认为看到UNARY_INVERT(整个字节码)会为答案添加任何内容?
Wooble 2014年

2
这个问题不是重复的!它询问的特定行为bool。这与~工作原理无关。实际上,对这个问题的有效答案可以避免提及2的补码以及如何~对整数进行运算。
Bakuriu 2014年

Answers:


240

int(True)1

1 是:

00000001

并且~1是:

11111110

这是-2两个补1

1翻转所有位,在结果数上加1,然后将结果解释为幅度的二进制表示,并添加一个负号(因为数字以1开头):

11111110  00000001  00000010 
                    
       Flip       Add 1

它是2,但由于MSB为1 ,所以符号为负。


值得一提:

想一想bool,您会发现它本质上是数字-它有两个值TrueFalse,它们只是整数1和0的“自定义”版本,它们的打印方式不同。它们是整数类型的子类int

因此它们的行为与1和0完全相同,只是bool重新定义strrepr以不同的方式显示它们。

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

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

1
@ofcapl只是想说:虽然int('1')也是typeerror异常,1但不是因为这是~'1'@Martijn 的子类在他的回答中添加了此信息。~Trueboolint
2014年

对于记录@ofcapl,此答案显示了正在发生的事情的二进制算术解释,而不是实际的字节码(这是从源代码编译的某种中间或操作级别的代码)。
Patrick M

5
@etrusco您在说什么语言?我确切地知道0在哪里True == -1,我知道许多地方可以说True == 1……
l4mpi 2014年

1
@etrusco @ l4mpi一些老式的BASIC -1用于TRUE。它具有很好的属性,即按位AND和OR运算符也适用于逻辑AND和OR(x & -1在相同情况下x && 1为非零,在C中为非零),只要您不关心短路。但是,据我所知,还没有主流语言-1用于TRUE。
Quuxplusone

1
形式逻辑定义truth为单值;一切都不truefalse。我知道的所有编程语言都将形式逻辑false颠倒过来,定义为单值(0),而所有这些都不是假的(true)。例如C#,尽管Javascript有点离群,但它具有多种真实性和多种虚假性
Nicholas Carey

45

Python bool类型是的子类int(出于历史原因;布尔值仅在Python 2.3中添加)。

由于int(True)1~True~1-2

有关为什么是的子类,请参见PEP 285boolint

如果需要布尔逆,请使用not

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

如果您想知道为什么这样~1-2,那是因为您正在反转一个有符号整数中的所有位;00000001变为1111110符号整数中的一个负数,请参见二进制补码

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

其中起始1位表示该值为负,其余位则对正数减去一的值进行反编码。


1
@GrijeshChauhan:两年的恭维,你可以使用struct.pack,作为bin(integer)format(integer, '08b')不带符号整数考虑。
马丁·皮特斯

@thefourtheye,MartijnPieters我尝试,但它是混淆例如bin(~True)bin(-2)bin(~1)都给人'-0b10' 如果-2表示是10那么为什么-迹象。
2014年

我自己的意思是2' 10补码-ve?
Grijesh Chauhan 2014年

1
@GrijeshChauhan您可以像这样获得负数和正数的补数表示法format(-2 % (1 << 32), "032b")
thefourtheye 2014年

2
@thefourtheye:我要使用位掩码:format(-2 & ((1 << 32) - 1), "032b")
Martijn Pieters

4

~True == -2,如果不奇怪 True的手段1 ~方式按位反转 ...

... 只要


编辑:

  • 修复整数表示和按位求反运算符之间的混合
  • 进行另一次抛光(信息越短,需要做的工作越多)

2
~并不表示“ 2s补码”。~意味着“按位倒置”
McKay 2014年

1
短语“一个人的补码”实际上并不是指运算,而是指按位存储整数的系统。计算机系统中实际上未使用的系统。
麦凯2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.