−0

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

-0(マイナスゼロ)は、負のゼロの表現であり、情報処理における整数のある種の符号付数値表現や多くの浮動小数点数表現に存在する。算術では通常、負のゼロはなく、-0 は 0 と同じとされる。

現在多くのコンピュータやプログラミング言語がサポートしている浮動小数点数の標準である IEEE 754 には +0 と -0 がある。標準において、その計算は無限大を含む拡張実数直線を対象としており、1/−0 = − および 1/+0 = +∞ となるよう2つのゼロが存在するとみなせる。すなわちこの場合に限っては0をある種の無限小のように扱っている。標準では一般に任意の非ゼロ数のゼロ除算は、正負どちらかの無限大になる。±0/±0 に限り、NaN になる。

数学では、負の符号がついたゼロは、たとえば解析学x → 0x → 0−、x → ↑0 などと表記される負の側から0に近づいていく片側極限の概念を反映している。科学では、-0 は 0 より小さいが -1 まで丸めるには絶対値が小さすぎる量を意味することがある。統計力学では、逆転分布状態の系において熱力学温度が -0 と見なされる場合がある。

IEEE 754 の仕様策定の際、符号付きのゼロを採用するといくつかの重要な問題で数値精度を容易に保つことができると主張され[1]、特に複素数の初等関数の計算が挙げられた[2]。一方で符号付きのゼロという概念は、-0 も +0 も同じ 0 だという多くの数学の領域での前提に反している。-0 を表現として許した場合、それが +0 と異なるビットパターンだということを忘れてプログラムを組むと、思わぬ間違いを産む原因となることがある。+0 と -0 は算術比較演算では等しいと判定されるが、ビットパターンが異なるため、一部演算では異なる結果を生じる。

表現法[編集]

よく使われている2進表現による固定小数点数(整数)の2の補数表現では、負のゼロは存在しない(かつては2進表現の固定小数点数で負数に1の補数表現を用いていてゼロに2種類が存在するシステムもあった。また符号と絶対値による表現法であれば自然に正負のゼロができる)。 1+7ビットの符号-仮数部表現の整数では、負のゼロは二進数で 1000 0000 と表現される。8ビットの1の補数表現では、負のゼロは二進数で 1111 1111 と表される。いずれの場合も正のゼロは 0000 0000 となる。

IEEE 754 の binary32 での負のゼロ

IEEE 754 の二進浮動小数点数では、ゼロは指数部と仮数部がゼロで表され、負のゼロの場合はさらに符号ビットが 1 となる。計算結果が負の極めて小さい値で算術アンダーフローとなった場合、負のゼロが結果として得られる。また、−1.0 * 0.0 の計算結果も負のゼロとなる。そのプログラミング言語リテラルが対応していれば、単に −0.0 と記述しても負のゼロになる。

IEEE 754 の十進浮動小数点数では、負のゼロの指数部は任意の正規の値で、仮数部は全てゼロであり、符号ビットが 1 で表される。

属性と操作[編集]

IEEE 754 では、正のゼロと負のゼロを各種演算で使用したときの振る舞いを規定している。計算結果は丸めモードの設定に影響される。

算術[編集]

乗除算は通常の符号の組み合わせと同じように扱われる。

  • \frac{-0}{ \left| x \right| } = -0\,\!x は0以外)
  • (-0) \cdot (-0) = +0\,\!
  • \left| x \right| \cdot (-0) = -0\,\!

加減算は値が相殺される場合特別に扱われる。

  • x + (\pm 0) = x\,\!
  • (-0) + (-0) = (-0) - (+0) = -0\,\!
  • (+0) + (+0) = (+0) - (-0) = +0\,\!
  • x - x = x + (-x) = +0\,\! (任意の有限のxについて、負方向への丸めの場合は −0)

負のゼロが存在するため、浮動小数点数の変数 xyz を使った式 z = -(x - y)z = (-x) - (-y)z = y - x と最適化することはできない。

他に次のような特別規則がある。

  • \sqrt{-0} = -0\,\! [3]
  • \frac{-0}{-\infty} = +0\,\! (除算の符号規則に従う)
  • \frac{\left|x\right|}{-0} = -\infty\,\!xがゼロでない場合、除算の符号規則に従う)
  • {\pm 0} \times {\pm \infty} = \mbox{NaN}\,\!NaNまたは割り込み発生)
  • \frac{\pm 0}{\pm 0} = \mbox{NaN}\,\!

比較[編集]

IEEE 754 規格は、C言語Java== 演算子のような通常の(数値としての)比較では、負のゼロと正のゼロは等しいと判定されることとしている。

IEEE 754 では copysign() 関数で、ゼロの符号をゼロでない何らかの数にコピーすることで正負を明確化することができる。C言語ではC99で標準となった。

Java では、Double クラスでの equals メソッドは負のゼロと正のゼロを区別する[4]。例えば、

Double negativeZero = new Double(-0.0);
negativeZero.equals(-0.0); // Result: true
negativeZero.equals( 0.0); // Result: false

以下は、後で紹介するものほどトリック的な方法となる。まず、(int)var のように普通に型キャストすると、負のゼロのない2の補数表現の整数では単なるゼロになってしまうので比較できない。

任意の非ゼロの値を除算して、正のゼロと負のゼロを区別できる。

  • 1.0 / +0.0 = +∞
  • 1.0 / -0.0 = -∞

型のパンニング英語版により、整数型としてアクセスし、ビットパターンとして比較する。C言語では、移植性のある技法ではないが(標準ではそのような操作の結果は「未定義」である。strict aliasing rule)、varIEEE 754の単精度である場合、

*(uint32_t *)&var == 0x80000000UL

で、負のゼロかどうか比較できる。

共用体を利用すれば、このようなアクセスが標準では「処理系定義」であるので、移植性が少しはマシである。

科学的用法[編集]

気象学では、-0度は 0度(華氏または摂氏)より低いが -1度とするほどではない温度を示し、統計的な意味(つまり1度単位で統計を取る場合)では重要なこともある。例えば、-0.2度がその例である。0度は負の範囲を含まないのでこれを 0度として統計処理することはできない。しかし、冬季の寒さを比較する際に日中の気温が 0度未満(氷点下)の日を数えることは基本であり、無視することができない。従って -1度に丸めるには絶対値が小さすぎる温度は -0度 と記録される。道路上などに設置してある気温・路温計でもそれを見ることが出来る。

統計力学関連の文脈で、負温度(0ケルビン未満の絶対温度)を持っている系を記述することも可能だが、直観とは逆にこれは極めて冷たいことを示すのではなく、いかなる正の絶対温度よりも熱いことを示している。何故なら反転分布のエネルギー係数は −1/Temperature となるからである。この文脈では -0度は他のどの負温度よりも最も高い温度である[5]

脚注[編集]

  1. ^ William Kahan, "Branch Cuts for Complex Elementary Functions, or Much Ado About Nothing's Sign Bit", in The State of the Art in Numerical Analysis (eds. Iserles and Powell), Clarendon Press, Oxford, 1987.
  2. ^ William Kahan, Derivatives in the Complex z-plane, p10.
  3. ^ Cowlishaw, Mike (2009年4月7日). “Decimal Arithmetic: Arithmetic operations – square-root”. speleotrove.com (IBM Corporation). 2010年12月7日閲覧。
  4. ^ Class Double
  5. ^ Kittel, Charles and Herbert Kroemer (1980). Thermal Physics (2nd ed.). W. H. Freeman Company. p. 462. ISBN 0-7167-1088-9. 

参考文献[編集]

関連項目[編集]