IEEE 754における負のゼロ
一般に複素数などの極座標表示においては、その偏角に 2 n π {\displaystyle 2n\pi } を加減しても複素数としては同じ値を示す、という性質がある。通常は代表値として、偏角を θ {\displaystyle \theta } とすると − π < θ ≤ + π {\displaystyle -\pi <\theta \leq +\pi } に制限するなどするが、マイナスゼロがある場合、 ( − 1.0 , + 0.0 i ) {\displaystyle (-1.0,+0.0i)} の偏角を + π {\displaystyle +\pi } とするのに対し ( − 1.0 , − 0.0 i ) {\displaystyle (-1.0,-0.0i)} の偏角を − π {\displaystyle -\pi } とする、といったように使い分ける用例がある。複素数を使わない場合でも、たとえば atan2(-0.0, -1.0) が − π {\displaystyle -\pi } になる実装がある。
標準では、C言語やJavaの == 演算子のような通常の(数値としての)比較では、負のゼロと正のゼロは等しいと判定されることとしている。
特に負のゼロのみの判定が可能な API としては、IEEE 754 の中では、copysign() 関数で、ゼロの符号をゼロでない何らかの数にコピーすることで正負を明確化することができる。C言語ではC99で標準となった。Java では、Double クラスでの equals メソッドは負のゼロと正のゼロを区別する。例えば、
以下は、後で紹介するものほどトリック的な方法となる。まず、(int)var のように普通に型キャストすると、負のゼロのない2の補数表現の整数では単なるゼロになってしまうので比較できない。
任意の非ゼロの値を除算して、正のゼロと負のゼロを区別できる。
1.0 / +0.0 = +∞
1.0 / −0.0 = −∞
型のパンニング(英語版)により、整数型としてアクセスし、ビットパターンとして比較する。C言語では、可搬(portable)な技法ではないが(標準ではそのような操作の結果は「未定義」である。strict aliasing rule)、var が IEEE 754の単精度である場合、
で、負のゼロかどうか比較できる。
共用体を利用すれば、このようなアクセスが標準では「処理系定義」であるので、可搬性(portability)が少しはマシである。