web-dev-qa-db-ja.com

Javaの-Infinity + Infinityの平方根はなぜですか?

Javaで平方根を見つけるために2つの異なる方法を試しました。

Math.sqrt(Double.NEGATIVE_INFINITY); // NaN
Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity

なぜ2番目の方法がNaN(1番目の方法と同じ)である期待される答えを返さないのですか?

35
Pratik

NaNは、真に未定義の(中間の)結果が得られたときに計算を続行するために返されます(IEEE 754の下)。 infinityは、オーバーフローが発生した後に計算を続行するために返されます。

したがって、動作

Math.sqrt(Double.NEGATIVE_INFINITY); // NaN

未定義の値が生成されたことが既知であるため(簡単におよび迅速に)指定されます。引数の符号のみに基づいています。

ただし、式の評価

Math.pow(Double.NEGATIVE_INFINITY, 0.5); // Infinity

オーバーフローと無効な操作の両方が発生します。ただし、無効な操作の認識は、2番目の引数の決定の精度に大きく依存します。 2番目の引数が前の丸め演算の結果である場合、exactly 0.5ではない可能性があります。したがって、2番目の引数の精度に対する結果の重大な依存を回避するために、それほど深刻ではない決定であるオーバーフローの認識が返されます。

例外を生成する代わりにフラグ値を返す理由を含む、IEEE 754標準の背後にある推論の詳細については、

すべてのコンピューター科学者が浮動小数点演算について知っておくべきこと(1991、David Goldberg)

の付録D

Sun Microsystems数値計算ガイド

48
Pieter Geerkens

Mathの-​​ ドキュメント で説明されているように動作します。

ために Math.sqrt

引数がNaNまたはゼロより小さい場合、結果はNaNです。

ために Math.pow

もし

  • 最初の引数が負のゼロであり、2番目の引数がゼロより小さいが有限の奇数の整数ではない、または
  • 最初の引数は負の無限大であり、2番目の引数はゼロより大きいが有限の奇数の整数ではありません。

結果は正の無限大です。

彼らがなぜそのデザインを選択したのかについては、Javaの作者に尋ねる必要があります。

30
piet.t