5

次の Java コードを検討してください。

String toParse = "1.7976931348623157E308"; //max value of a double in java        
double parsed = Double.parseDouble(toParse);
System.out.println(parsed);

言及された1.7976931348623157E308すべての値は理にかなっていて、正しい出力が得られます。

1.7976931348623158E308ここで、 (インクリメントされる前の最後の桁)を解析しようとするとE、コンソールに最大値が出力されます!
解析を試みた後にのみ1.7976931348623159E308(最後の桁が増加しました)、大きい方が取得されInfinityます。
対応する負の値についても同じ動作です。

... 8E308が解析され、解析され... 7E308ないのはなぜInfinityですか?

4

1 に答える 1

10

SE 7 バージョンの parseDouble ドキュメントは、次のような valueOf ドキュメントを参照しています。

最も近い値に丸める規則は、オーバーフローおよびアンダーフローの動作も意味することに注意してください。s の正確な値の大きさが十分に大きい場合 ((MAX_VALUE + ulp(MAX_VALUE)/2 以上)、double への丸めは無限大になり、s の正確な値の大きさが十分に小さい場合 (以下) MIN_VALUE/2 以上)、浮動小数点数への丸めはゼロになります。

これは、double 型への丸めが、IEEE 754 浮動小数点演算の通常の最も近い値への丸め規則によるものであるというステートメントと一致しています。

最初に指数の制限を無視して最も近い浮動小数点数を計算し、次に指数が適合するかどうかを確認することによって変換が行われることを想像する必要があります。Double.MAX_VALUE は、そのルールの下で、それより厳密に大きいいくつかの数値に最も近い数値です。

これが通常の丸め動作であることを確認するには、次のプログラムを検討してください。

    public class Test {
      public static void main(String[] args) {
        double ulp = Math.ulp(Double.MAX_VALUE);
        System.out.println(ulp);
        System.out.println(Double.MAX_VALUE);
        System.out.println(Double.MAX_VALUE+ulp/2.0000000001);
        System.out.println(Double.MAX_VALUE+ulp/2);
      }
    }

以下を出力します。

1.9958403095347198E292
1.7976931348623157E308
1.7976931348623157E308
Infinity

Double.MAX_VALUE に ulp の半分よりわずかに小さいものを追加しても、それは変わりません。ulp の半分のオーバーフローを無限に追加します。

于 2012-11-24T03:08:35.203 に答える