2017-08-21 8 views
2

挙動(+0.0)

float f = -0.0; // Negative 

及び結果はtrueなり負のゼロ

f == -0.0f 

と比べ。どちらの場合も真であることが結果なぜ

しかし

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; 
    } 
} 

出力:署名した負のゼロtrueゼロと比較しなければならないためだ

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

true 
+0

[その他](https://stackoverflow.com/a/45790355/4711812)に記載されているように、あなたは今日質問しています:C++に負のゼロというものはありません。 – muXXmit2X

+1

それはなぜでしょうか? "負の0"はありません。どちらもゼロです。もちろん、0との比較はtrueを返します。 – Zinki

+0

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

答えて

7

:すなわち-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。また、これら2つの表現は、等号を比較しなければならないことが規定されているので、定義によって:

+0.0 == -0.0 

それはその紙What Every Computer Scientist Should Know About Floating Point Arithmetic、デヴィッド・ゴールドバーグ、上のIEEE-754ページにリンクされ1991年から1903年(で、そうである理由についてはIEEEウェブサイト)を書き込む:X < 0は、Xがアンダーフローしている小さな負の数を表すと仮定したとき、ログ0を定義することが自然である= IEEE演算で

を-∞とNaNになるようにXをログゼロ。符号付きのゼロのおかげで、xは負になるので、logは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の実装がサポートしている場合(例えばによるIEEE浮動小数点を使用して)ゼロに署名し、署名された零点を検出することができるstd::signbit()ような機能を導入し、浮動小数点値の間の符号ビットをコピーすることができstd::copysign()。このようなことはさておき、私はC++標準のリファレンスには、ゼロを言及するだけでなく、それらを比較した結果であるべきことは言及していません。

C++標準では浮動小数点表現も規定していません。実装定義です。

これらの観察結果は、符号付きゼロのサポートまたはそれらを比較した結果が、実装(別名コンパイラ)がサポートする浮動小数点表現によって決まることを示唆しています。

IEEE-754は、最新の実装(すなわちコンパイラ)で使用される最も一般的な(ただし唯一ではない)浮動小数点表現です。未満:5.11、第二段落「-POINT算術を浮動ためのIEEE規格」IEEE-758の現在(2008年発行)のバージョンは、(太字強調鉱山)

つの相互に排他的な関係が考えられると言います、は、,,より大きく、は、である。最後のケースは、少なくとも1つのオペランドがNaNの場合に発生します。すべてのNaNは、の順序付けされていないとそれ自身を含むすべてを比較します。 比較はゼロの符号を無視する(したがって+0 = -0)。同じ符号の無限オペランドは、と等価のものをと比較します。

+1

厳密に言えば、IEEE754は 'std :: signbit'が動作するためには十分ではありません。 – MSalters

+0

真であるが、 'signbit()'とIEEE754を念頭に置いて明記された他のいくつかの機能が導入されました。とにかく、それに応じて答えを更新します。 – Peter