2014-11-05 121 views
5

我可能會錯過一些基本的東西,但考慮到這個解釋器會話:爲什麼-0.0和0.0不一樣?

>>> -0.0 is 0.0 
False 
>>> 0.0 is 0.0 
True 
>>> -0.0 # The sign is even retained in the output. Why? 
-0.0 
>>> 

你會認爲,Python解釋器會意識到-0.00.0是相同的數字。事實上,他們比較爲等於:

>>> -0.0 == 0.0 
True 
>>> 

那麼,爲什麼Python的兩個之間的區別,並生成-0.0一個全新的對象?它不整數做到這一點:

>>> -0 is 0 
True 
>>> -0 # Sign is not retained 
0 
>>> 

現在,我意識到,浮點數是一個巨大的與計算機上的問題來源,但這些問題總是針對其準確性。例如:

>>> 1.3 + 0.1 
1.4000000000000001 
>>> 

但是,這不是一個準確性問題,是嗎?我的意思是,我們正在談論這裏的數字的符號,而不是小數點。


我可以重現這一行爲在這兩個的Python 2.7和Python 3.4,所以這不是一個特定版本的問題。

+1

我相信這是IEEE 754浮點表示的一個特性,這意味着它不是特定於Python。 – 2014-11-05 19:04:41

+0

整數溢出可能是更嚴重的「計算機問題的根源」。 – tmyklebu 2014-11-05 22:35:44

+0

爲什麼你使用'is'進行數字比較?您的許多問題與簽名的零無關:嘗試'x = 2.3','y = 2.3',接着'x是y'。然後,爲了好玩,試試'x = 2.3; y = 2.3'(全部在一行上),後面是'x是y'。 – 2014-11-06 12:21:28

回答

11

在IEEE754中,浮點數的格式,符號是一個單獨的位。所以-0.0和0.0有所不同。 整數使用二進制補碼來表示負數;這就是爲什麼只有一個0

使用is只有你真的想比較對象的實例。否則,特別是對號碼,使用==

>>> 1999+1 is 2000 
False 

>>> 0.0 == -0.0 
True 
+0

我接受你的答案,因爲你解釋了浮動情況以及整數。但是,你能想到任何真實世界的'-0.0'用例嗎?我知道它有一些理論上的用途,但它似乎只是阻礙了它的發展。 – iCodez 2014-11-05 19:30:38

+7

@iCodez:帶符號的零有助於實現複雜的數學函數。規範文件是:William Kahan,複雜基本函數的分支切割,或者關於Nothing的符號位。在:數值分析的藝術狀態,克拉倫登出版社,牛津,1987年。在線副本很容易通過Google Scholar找到。 – njuffa 2014-11-05 19:50:46

+0

請注意,Python沒有特別強制IEEE-754。 [參考](https://docs.python.org/3/reference/datamodel.html#the-standard-type-hierarchy)說:「這些代表機器級雙精度浮點數。你受制於底層的機器體系結構(以及C或Java實現)用於可接受的範圍和處理溢出。「但是在大多數平臺和實現中,這意味着IEEE-754雙打或者非常接近它。 – abarnert 2014-11-05 20:35:49

4

因爲這兩個數字的二進制表示是不同的。在0.0中,第32位爲0,在-0.0中第32位爲1.

+1

python中的浮點數是64位。 – Daniel 2014-11-05 19:11:39

+0

好的。答案仍然大致相同。浮點中的最後一位是符號位。正值1表示負值。 – 2014-11-05 19:18:06

+0

實際上,在2.x中,Python中的浮點數一般未指定,並且在CPython中指定爲「用於構建解釋器的C編譯器中的任何」double「。 3。x,他們對它進行了一些清理,並在實現中將它們指定爲「一臺機器」double「」,但請注意「您受制於底層機器體系結構(以及C或Java實現)」。 – abarnert 2014-11-05 19:58:49

8

的IEEE標準浮點運算(IEEE 754)定義的signed zeroes列入。理論上它們允許您區分負數下溢和正數underflow

就python而言,使用==而不是is來比較數字。