タイトル通りです。
bitを比較すると当然等値ではないですが、floatとして比較すると等値です。
#include <iostream>
#include <bitset>
using namespace std;
union d {
float f;
bitset<32> b;
};
int main()
{
d x{0}, y{0};
y.f *= -1;
assert(x.f == y.f); //等値
assert(x.b != y.b); //等値ではない
cout << x.f << endl;
cout << y.f << endl;
}
//実行結果
0
-0
これはIEEEの浮動小数点に関する規格に**+0と-0は区別するけど、orderの比較では等価として扱うよ**と定められているからです。
https://en.wikipedia.org/wiki/IEEE_754
そもそもなぜ0と-0なんてあるのか
整数型が補数で負の値を表すのに対して、浮動小数点型は最上位ビットの違いで符号を表します。
なので浮動小数点型では-0と0という2つの値を表すことができます。
floatだよ
x: 0 -> 00000000000000000000000000000000
y:-0 -> 10000000000000000000000000000000
これは1/xみたいに0周辺で不連続な関数において、0と-0の違いがあると実装が楽だからとか。
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
float a = 0, b = -a;
//0と-0で結果の変わる演算
cout << 1/a << endl;
cout << 1/b << endl;
}
//実行結果
inf
-inf
##どうすれば区別できるの?
c++の場合はどうしても比較したいときは0周辺のときだけstd::signbitとかつかうと良いのですかね。
float a = 0, b = -a;
cout << std::signbit(a) << endl; // 0
cout << std::signbit(b) << endl; // 1
pythonとかだとどうすればいいんでしょうか。。。わかりません!