背景
在對Double類型的數據進行計算操作,將結果轉化為BigDecimal時拋出了下面的異常,進行了Debug才發現了問題原因,同時也暴露出了自己在一些基礎知識上還有些欠缺。
Exception in thread "main" java.lang.NumberFormatException: Infinite or NaN at java.math.BigDecimal.<init>(BigDecimal.java:895) at java.math.BigDecimal.<init>(BigDecimal.java:872) at com.lingyejun.authenticator.DoubleTest.main(DoubleTest.java:13)
概念補充
在java中進行數字類型運算的時,之前一直有一種錯誤的觀念,即進行除法運算時當除數為0時在運行時會拋出java.lang.ArithmeticException: / by zero運行時異常。如此想當然的以為對於浮點類型如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); } }
運算結果為“d1=Infinity d2=-Infinity d3=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");
撥雲見日探究清楚之后,一切都是那樣的理所應當。