Java浮點類型精度問題

Java浮點類型精度問題


public static void main(String[] args) throws Exception {
    float a = 1.0f - 0.9f;
    float b = 0.9f - 0.8f;
    System.out.println(a == b);//false

    Float c = a;
    Float d = b;
    System.out.println(c.equals(d));//false

    System.out.println(a);//0.100000024
    System.out.println(b);//0.099999964
}
public static void main(String[] args) throws Exception {
    double a = 1.0 - 0.9;
    double b = 0.9 - 0.8;
    System.out.println(a == b);//true

    Double c = a;
    Double d = b;
    System.out.println(c.equals(d));//true

    System.out.println(a);//0.09999999999999998
    System.out.println(b);//0.09999999999999998
}

“浮點數之間的等值判斷,基本數據類型不能用 == 來比較,包裝數據類型不能用equals來判斷。”

​ —— 《Java開發手冊》

浮點數值不適用於無法接收舍入誤差的計算中。這種舍入誤差的主要原因是浮點數採用二進制系統表示,而在二進制系統中無法精確地表示分數1/10,就好像十進制無法精確地表示分數1/3一樣。

解決辦法

  1. 指定一個誤差範圍,兩個浮點數的差值在此範圍之內,才認爲是相等的。
public static void main(String[] args) throws Exception {
    float a = 1.0f - 0.9f;
    float b = 0.9f - 0.8f;
    float diff = 1e-6f;
    //absolute value
    System.out.println(Math.abs(a - b) < diff);//true
}
  1. 使用BigDecimal 來定義值,再進行浮點數的運算操作。
public static void main(String[] args) throws Exception {
    BigDecimal a = BigDecimal.valueOf(1.0);
    BigDecimal b = BigDecimal.valueOf(0.9);
    BigDecimal c = BigDecimal.valueOf(0.8);
    
    BigDecimal x = a.subtract(b);
    BigDecimal y = b.subtract(c);
    System.out.println(x.equals(y));//true
    
    System.out.println(x);//0.1
    System.out.println(y);//0.1
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章