2014-02-19 95 views
128

在Python控制檯:爲什麼〜真的結果是-2?

~True 

給我:

-2 

爲什麼?有人可以用二進制向我解釋這個特殊情況嗎?

+21

,因爲'〜1'是'-2',請嘗試:'True == 1' –

+13

準確地說:「True爲1」並不是真的,但「True == 1」 。 – Bach

+3

你真的認爲看到'UNARY_INVERT'(整個字節碼)會給答案添加任何東西嗎? – geoffspear

回答

232

什麼是int(True)?它是1

1是:

00000001 

~1是:

11111110 

哪個-2Two's complement

翻轉所有的位,添加1到所得號碼和interp漚結果作爲幅值的二進制表示,並添加負的符號(由於數以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')'也是'1',但'〜'1''是一個typeerror異常,而'〜True'不是這是因爲'bool'是'int' @ Martijn在他的回答中加入了這個信息。 –

+0

爲了記錄@ofcapl,這個答案顯示了正在發生什麼的二進制算術解釋,而不是實際的[字節碼](http://en.wikipedia.org/wiki/Bytecode)(這可能是某種中間或從源編譯的操作級代碼)。 –

+1

@PatrickM我想他是指二進制算術,而不是*字節碼* .. – Maroun

44

Python bool類型是int的子類(由於歷史原因;布爾值僅在Python 2.3中添加)。

由於int(True)1,~True~1-2

請參閱PEP 285爲什麼boolint的子類。

如果你想布爾逆,使用not

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

如果你想知道爲什麼~1-2,那是因爲你是反轉所有位有符號整數; 00000001變得1111110其中在簽署整數是一個負數,見Two's complement

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

其中初始1位意味着該值是負的,而其餘位編碼正數減去的倒數一。

+3

我們有任何函數來顯示Python中的位? –

+6

@GrijeshChauhan ['bin'](http://docs.python.org/2/library/functions.html#bin) – thefourtheye

+1

@GrijeshChauhan:對於兩個人的誇獎,你可以使用'struct.pack'作爲'bin(整數)'或'格式(整數,'08b')'不考慮有符號整數。 –

4

~True == -2並不奇怪如果True意味着1~裝置按位反轉 ...

... 提供


編輯:

  • 固定整數表示和位反轉操作者之間的混合
  • 施加另一拋光(該消息的更短的,需要做的工作越多)
+2

「〜」並不意味着「2s補碼」。 '〜'的意思是「按位反轉」 – McKay

+0

http://docs.python.org/2/library/operator.html – McKay

+1

短語「Ones'complement」並不真正指向一個操作,它指的是一個操作以比特存儲整數的系統。計算機系統中未實際使用的系統。 – McKay