java.lang.Number FormatException:Infinite or NaNの原因の浮動小数点タイプの除数は0の結果を探究します。

2262 ワード

背景
Doubleタイプのデータを計算操作して、結果をBigDecimalに変換した時に以下の異常を投げました。Debugを行って、問題の原因を発見しました。また、自分の基礎知識に不足があることを暴露しました。
Exception in thread "main" java.lang.NumberFormatException: Infinite or NaN
    at java.math.BigDecimal.(BigDecimal.java:895)
    at java.math.BigDecimal.(BigDecimal.java:872)
    at com.lingyejun.authenticator.DoubleTest.main(DoubleTest.java:13)
概念の追加
javaでデジタルタイプ演算を行う場合、除算時に除数が0になるとjava.lang.Arthmetic Exception:/byゼロが動作すると異常という考えがあります。このように考えると、浮動小数点タイプはFloatやDoubleのように、次のコードで問題を説明できると思います。
package com.lingyejun.authenticator;

public class DoubleTest {

    public static void main(String[] args) {
        Double d1 = 10 / 0D;
        Double d2 = -10 / 0D;
        Double d3 = 0.0 / 0D;
        System.out.println("d1=" + d1 + " d2=" + d2 + " d3=" + d3);
    }
}
演算結果は「d 1=Infinity d 2=-Infinity d 3=NaN」です。何ですか?数字演算で文字列が計算されますか?印刷されたInfinity、-Infinit、NaNは文字列ではなく、doubleタイプの定数です。ソースの注釈を見れば分かります。
/**
 * A constant holding the positive infinity of type
 * {@code double}. It is equal to the value returned by
 * {@code Double.longBitsToDouble(0x7ff0000000000000L)}.
 */
public static final double POSITIVE_INFINITY = 1.0 / 0.0;

/**
 * A constant holding the negative infinity of type
 * {@code double}. It is equal to the value returned by
 * {@code Double.longBitsToDouble(0xfff0000000000000L)}.
 */
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;

/**
 * A constant holding a Not-a-Number (NaN) value of type
 * {@code double}. It is equivalent to the value returned by
 * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
 */
public static final double NaN = 0.0d / 0.0;
正無限:POSITIVE_INFINITYは、正の数をゼロで割って正のものにします。
マイナス無限:NEGATIVE_INFINITYは、マイナスをゼロで割るとマイナスが無限になります。
数字ではない:NaN、0を0で割ると非数字になります。 
異常な原因
BigDecimal類におけるDoubleタイプデータに対する構造方法を確認することにより、BigDecimalオブジェクトを構築する際に、構造方法によって導入されたDoubleタイプが無限大または非数値の場合にはNumberFormatException異常を投げることがわかった。
public BigDecimal(double val, MathContext mc) {
        if (Double.isInfinite(val) || Double.isNaN(val))
            throw new NumberFormatException("Infinite or NaN");
ダーティハリー4が解明されたら、すべてはそのような当たり前のことです。