Java 浮點數運算 (float/double) 引入 IEEE 754 標準定義的兩個特殊值:**Infinity (無窮大)** 與 **NaN (Not a Number)**,優雅處理除零、非法運算等異常情況,避免整型運算拋出 ArithmeticException 導致程式崩潰。
當非零浮點數除以 0.0 時產生。Double 與 Float 定義常量:
// Double
public static final double POSITIVE_INFINITY = 1.0 / 0.0; // 正無窮
public static final double NEGATIVE_INFINITY = -1.0 / 0.0; // 負無窮
// Float
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;
0.0 / 0.0、Infinity - Infinity、Infinity * 0、Math.sqrt(-1) 等非法運算產生。NaN 不等於任何值,包括它自己。
public static final double NaN = 0.0d / 0.0;
public class FloatSpecialValues {
public static void main(String[] args) {
float fPos = Float.POSITIVE_INFINITY;
float fNeg = Float.NEGATIVE_INFINITY;
double dPos = Double.POSITIVE_INFINITY;
double dNeg = Double.NEGATIVE_INFINITY;
// t1: Float 與 Double 無窮值相等
System.out.println("Float.POS == Double.POS: " + (fPos == dPos)); // true
System.out.println("Float.NEG == Double.NEG: " + (fNeg == dNeg)); // true
// t2: 無窮乘 0 → NaN
System.out.println("Infinity * 0 = " + (fPos * 0)); // NaN
System.out.println("-Infinity * 0 = " + (fNeg * 0)); // NaN
// t3: 無窮參與運算 (除乘 0 外) 結果仍為無窮
System.out.println("Infinity + 10000 == Infinity: " + (fPos == (fPos + 10000))); // true
System.out.println("Infinity * 10000 == Infinity: " + (fPos == (fPos * 10000))); // true
System.out.println("Infinity / 0 == Infinity: " + (fPos == (fPos / 0))); // true
// t4: 判斷是否為無窮
System.out.println("Double.isInfinite(dPos): " + Double.isInfinite(dPos)); // true
// --- NaN 判斷 ---
double nan = Double.NaN;
System.out.println("NaN == NaN: " + (nan == nan)); // false! 關鍵特性
System.out.println("Double.isNaN(nan): " + Double.isNaN(nan)); // true (正確判斷方式)
System.out.println("Float.isNaN(Float.NaN): " + Float.isNaN(Float.NaN)); // true
}
}
| 判斷目標 | 正確方法 | 錯誤示範 |
|---|---|---|
| 是否為 +Infinity / -Infinity | Double.isInfinite(val) / Float.isInfinite(val) | val == Double.POSITIVE_INFINITY (僅能判正無窮,且風格差) |
| 是否為 NaN | Double.isNaN(val) / Float.isNaN(val) | val == Double.NaN 永遠為 false |
| 是否為有限數值 (非無窮、非 NaN) | !Double.isInfinite(val) && !Double.isNaN(val) 或 JDK 8+ Double.isFinite(val) |
float/double,必須用 BigDecimal。浮點數固有精度缺失 (如 0.1+0.2!=0.3) 比特殊值更隱蔽危險。Infinity 表示溢出邊界,NaN 表示未定義結果,配合 isInfinite/isNaN 做分支控制。Infinity/NaN,但某些嚴格解析器可能拒絕。跨語言交互需確認對端解析行為。Double.compare() 定義 NaN == NaN、NaN > 正無窮、-0.0 < +0.0,符合 IEEE 754 totalOrder,可安全用於排序。掌握 isInfinite、isNaN 兩大判斷神器,告別浮點數邊界條件 Bug!