コンテンツにスキップ
Wikipedia

−0

出典: フリー百科事典『ウィキペディア(Wikipedia)』

これはこのページの過去の版です。Giant2007 (会話 | 投稿記録) による 2016年1月14日 (木) 04:45 (個人設定で未設定ならUTC)時点の版 (→‎関連項目: リンクを追加)であり、現在の版 とは大きく異なる場合があります。

Giant2007 (会話 | 投稿記録)による2016年1月14日 (木) 04:45時点の版 (→‎関連項目: リンクを追加)
曖昧さ回避 この項目では、数の表現について説明しています。広瀬正のSF小説については「マイナス・ゼロ」をご覧ください。

-0(マイナスゼロ)、あるいは負のゼロとは、数値のゼロにマイナスの符合をつけたものである。

通常の算術では、負のゼロは正のゼロである+0と同一であると見なされるが、両者を分けて考える方が望ましい場合や、分けて考えざるを得ない場合がある。

そのようなケースとして、以下のものがある

最初のものについては片側極限の項目、最後のものは負温度の項目を参照。 本項ではそれ以外の2つのケースについて取り扱う。


なお、負のゼロと同種の理由で、正のゼロである「+0」と符合のないゼロである「0」を区別しなければならない場合もあるが、本項ではこの問題については割愛し、 「+0」と「0」を同一視する。

数値表現としての負のゼロ

数値表現において符合の概念をゼロにも適応した結果として負のゼロが生じる場合がある。

例えば整数をN進法で表現する場合、ゼロ以外の数は、

  • +(数値)
  • -(数値)

のいずれかの形に一意に表現できる。 しかしゼロのみは

  • +0
  • -0

の二種類の表現が可能である為、負のゼロの問題が生じる。

この事が原因で、0のみ例外処理が必要になる場合がある。

例えば2つの数値

  • A=(符合1)(数値1)
  • B=(符合2)(数値2)

が等しいかどうかを判定するために以下のようなプログラムを書くとバグを作り込むこととなる:

  • if(符合1と符合2が等しく、数値1も数値2と等しい)
    • 「A=B」と出力
  • else
    • 「A≠B」と出力

このプログラムにA=+0、B=-0を代入すると、本来は「A=B」を出力しなければならないはずだが、両者の符合が異なることが原因で「A≠B」を出力してしまう。

このように負のゼロは、プログラムにおいてバグの原因になってしまうので、慎重に取り扱う必要がある。

この種の問題の根本的解決としては、そもそも負のゼロが生じない数値表現を選ぶ、という方法があるが、他の問題との兼ね合いによっては、必ずしもこれが最良な解決になるとは限らない。

コンピューターでは補数を利用して負数を表現する事が多いが、同じ補数でも基数の補数 を利用した場合には負のゼロが生じないのに対し、減基数の補数 を用いた場合には負のゼロが生じる。

IEEE 754における負のゼロ

この節に雑多な内容が羅列されています 事項を箇条書きで列挙しただけの節は、本文として組み入れるか、または整理・除去する必要があります。(2016年1月)

現在多くのコンピュータやプログラミング言語がサポートしている浮動小数点数の標準である IEEE 754 には通常の 0(以下 +0 と書く)と -0 がある。

標準において、その計算は無限大を含む拡張実数直線を対象としており、1/−0 = − および 1/+0 = +∞ となるよう2つのゼロが存在するとみなせる。すなわちこの場合に限っては0をある種の無限小のように扱っている。標準では一般に任意の非ゼロ数のゼロ除算は、正負どちらかの無限大になる。±0/±0 に限り、NaN になる。

IEEE 754 の仕様策定の際、符号付きのゼロを採用するといくつかのクリティカルな問題で数値的な正確さ(accuracy)の達成が(精度(precision)ではない)容易になると主張され[1] 、特に複素数の初等関数の計算が挙げられた[2] 。一方で符号付きのゼロという概念は、-0 も +0 も同じ 0 だという多くの数学の領域での前提に反している。一部の計算において -0 の存在を忘れてプログラムを組むと、思わぬバグの原因となることがある。算術比較演算では等しいと判定されるが、一部演算では異なる結果を生じる[3]

表現法

IEEE 754 の binary32 での負のゼロ

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

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

属性と操作

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

算術

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

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

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

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

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

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

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

複素数など

一般に複素数などの極座標表示においては、その偏角に 2 n π {\displaystyle 2n\pi } {\displaystyle 2n\pi } を加減しても複素数としては同じ値を示す、という性質がある。通常は代表値として、偏角を θ {\displaystyle \theta } {\displaystyle \theta } とすると π < θ + π {\displaystyle -\pi <\theta \leq +\pi } {\displaystyle -\pi <\theta \leq +\pi } に制限するなどするが、マイナスゼロがある場合、 ( 1.0 , + 0.0 i ) {\displaystyle (-1.0,+0.0i)} {\displaystyle (-1.0,+0.0i)}の偏角を + π {\displaystyle +\pi } {\displaystyle +\pi } とするのに対し ( 1.0 , 0.0 i ) {\displaystyle (-1.0,-0.0i)} {\displaystyle (-1.0,-0.0i)}の偏角を π {\displaystyle -\pi } {\displaystyle -\pi } とする、といったように使い分ける用例がある。複素数を使わない場合でも、たとえば atan2(-0.0, -1.0) π {\displaystyle -\pi } {\displaystyle -\pi } になる実装がある。

比較

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

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

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

DoublenegativeZero=newDouble(-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度 と記録される。道路上などに設置してある気温・路温計でもそれを見ることが出来る。

脚注

  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. ^ 「ビットパターンが異なるため」ではない。#複素数などの節を参照のこと。
  4. ^ Cowlishaw, Mike (7 April 2009). "Decimal Arithmetic: Arithmetic operations – square-root". speleotrove.com (IBM Corporation). 2010年12月7日閲覧。
  5. ^ Class Double

参考文献

関連項目

AltStyle によって変換されたページ (->オリジナル) /