首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 浮點數特殊值全解析:NaN 與 Infinity 的產生、判斷與運算規則

     編輯:Java 綜合教學

Java 浮點數特殊值全解析:NaN 與 Infinity 的產生、判斷與運算規則

Java 浮點數運算 (float/double) 引入 IEEE 754 標準定義的兩個特殊值:**Infinity (無窮大)** 與 **NaN (Not a Number)**,優雅處理除零、非法運算等異常情況,避免整型運算拋出 ArithmeticException 導致程式崩潰。

1. Infinity:無窮大的表示與分類

當非零浮點數除以 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;

2. NaN:非數字的表示

0.0 / 0.0、Infinity - Infinity、Infinity * 0、Math.sqrt(-1) 等非法運算產生。NaN 不等於任何值,包括它自己。

public static final double NaN = 0.0d / 0.0;

3. 運算規則實戰驗證

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
    }
}

4. 核心判斷方法總結 (必須掌握)

判斷目標正確方法錯誤示範
是否為 +Infinity / -InfinityDouble.isInfinite(val) / Float.isInfinite(val)val == Double.POSITIVE_INFINITY (僅能判正無窮,且風格差)
是否為 NaNDouble.isNaN(val) / Float.isNaN(val)val == Double.NaN 永遠為 false
是否為有限數值 (非無窮、非 NaN)!Double.isInfinite(val) && !Double.isNaN(val) 或 JDK 8+ Double.isFinite(val)

5. 實際開發避坑指南

  • 金融/精密計算:嚴禁用 float/double,必須用 BigDecimal。浮點數固有精度缺失 (如 0.1+0.2!=0.3) 比特殊值更隱蔽危險。
  • 數學庫/科學計算:合理利用 Infinity 表示溢出邊界,NaN 表示未定義結果,配合 isInfinite/isNaN 做分支控制。
  • 序列化/傳輸:JSON (Gson/Jackson) 預設支援 Infinity/NaN,但某些嚴格解析器可能拒絕。跨語言交互需確認對端解析行為。
  • 比較排序:Double.compare() 定義 NaN == NaN、NaN > 正無窮、-0.0 < +0.0,符合 IEEE 754 totalOrder,可安全用於排序。

掌握 isInfinite、isNaN 兩大判斷神器,告別浮點數邊界條件 Bug!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved