2017-08-21 51 views
2

在我的代碼比較負零(-0.0)的,行爲與正零(0.0)

float f = -0.0; // Negative 

並用負零

f == -0.0f 

結果相比較將是true

float f = 0.0; // Positive 

負零

f == -0.0f 

還比較,結果將是true而不是false

爲什麼在兩種情況下會導致是真的嗎?


這裏是a MCVE to test it (live on coliru)

#include <iostream> 

int main() 
{ 
    float f = -0.0; 

    std::cout<<"==== > " << f <<std::endl<<std::endl; 

    if(f == -0.0f) 
    { 
     std::cout<<"true"<<std::endl; 
    } 
    else 
    { 
     std::cout<<"false"<<std::endl; 
    } 
} 

輸出:

==== > -0 // Here print negative zero 

true 
+0

正如你今天所問的[其他](https://stackoverflow.com/a/45790355/4711812)問題所述:在C++中不存在負數爲零的情況。 – muXXmit2X

+1

爲什麼不是? 沒有「負0」,它只是零。所以當然與0比較的結果是正確的。 – Zinki

+0

https://stackoverflow.com/questions/43086963/is-negative-zero-always-equal-zero – CBroe

回答

7

這是因爲簽署負零必須比較true零:即-0.0 == 0.0-0f == 0f,並-0l == 0l

這是C++編譯器支持的任何浮點方案的要求。

(注意,大多數平臺上,這些天使用IEEE754浮點,而這種行爲是在說明書中明確記載。)

-2

因爲0.0F和等於-0.0f是零的同一底片爲零

+4

如果他們是相同的,他們會打印相同的。他們不一樣。但是他們比較相等=='。 –

+0

Q:_「爲什麼0.0f和-0.0f相等?」_ ... A:_「因爲」_。這是一個**糟糕的答案:-1。 – YSC

10

C++中的浮點運算通常是IEEE-754。這個規範不同於實數集的數學定義。

這個標準defines two different representations for the value zero: positive zero and negative zero。它還定義了這兩個陳述必須比較平等的,所以顧名思義:

+0.0 == -0.0 

至於爲什麼是這樣,在其紙What Every Computer Scientist Should Know About Floating Point Arithmetic,大衛·戈德堡,1991年至1903年(在對IEEE-754頁鏈接在IEEE網站)寫道:

在IEEE算術,很自然地定義日誌0 =-∞和日誌x至是爲NaN當x < 0假設x表示的是下溢到一個小的負數零。由於簽名爲零,x將爲負數,因此日誌可以返回NaN。但是,如果沒有帶符號的零,則日誌函數無法區分下溢的負數與0,因此必須返回-∞。

+1

關於IEEE-754的進一步解讀:[IEEE標準754浮點數](http://steve.hollasch.net/cgindex/coding/ieeefloat.html)Steve Hollasch,2015-12-2。 – YSC

+0

'log'參數有點有問題。 IEEE 754-2008建議'log(+0.0)'和'log(-0.0)'應該返回負無窮大。 (請參見第9.2.1節「特殊值」。) –

0

C++ 11導入的功能類似於std::signbit()其可以檢測符號的零,並std::copysign(),可以複製符號位浮點值之間,如果實現支持符號零(例如,由於使用IEEE浮點)。除此之外,我不知道任何C++標準中的引用,甚至提到了帶符號的零,更不用說比較它們的結果了。更不用說比較它們的結果了。

C++標準也沒有規定任何浮點表示 - 是實現定義的。

儘管不是確定性的,但這些觀察結果表明支持帶符號的零或者比較它們的結果將取決於實現(aka編譯器)支持的浮點表示。

IEEE-754是現代實現(即編譯器)使用的最常見(儘管不是唯一的)浮點表示形式。 「浮 - 點運算IEEE標準」第5.11節,第二段目前(2008年出版)版本的IEEE-758,說(粗體強調雷)

四個相互排斥的關係是可能的:少,等於,大於無序。最後一種情況出現在至少一個操作數是NaN的情況下。每個NaN都應將無序與包括其本身在內的所有內容進行比較。 比較應忽略零的符號(所以+0 = -0)。同一符號的無限操作數必須比較等於

+1

嚴格地說,IEEE754是_sufficient_,但沒有必要使'std :: signbit'工作。 – MSalters

+0

誠然,雖然引入了signbit()以及IEEE754明確規定的一些其他功能。無論如何,將相應地更新答案。 – Peter