5

代碼:Java float比double更精確嗎?

class Main { 
    public static void main (String[] args) { 
     System.out.print("float: "); 
     System.out.println(1.35f-0.00026f); 
     System.out.print("double: "); 
     System.out.println(1.35-0.00026); 
    } 
} 

輸出:

float: 1.34974 
double: 1.3497400000000002 

??? float得到了正確的答案,但是double從沒有添加額外的東西,爲什麼?

是不是應該比float更精確?

+2

試試這個**的System.out.println( 「%20F」 的String.format(,1.35f-0.00026f)); ** – lummycoder

回答

8

一個浮點數是4個字節寬,而一個double是8個字節寬。

檢查What Every Computer Scientist Should Know About Floating-Point Arithmetic

當然雙具有更高的精度,因此已略少舍入誤差。

將無限多個實數擠壓成有限位數 需要近似表示法。雖然無限多個整數,但在大多數程序中,整數計算的結果可以以32位存儲。相比之下,給定任意固定位數,大多數使用實數的計算將產生不能使用那麼多位精確表示的數量。 因此,浮點計算的結果必須按 的順序進行四捨五入以適應其有限表示。這個舍入錯誤是浮點計算的特徵 。

在一個側面說明: -

,如果你想準確的十進制值,則使用java.math.BigDecimal

2

如果你知道一些關於規則轉換值我會建議 至字符串,這些文件由的文檔指定Double.toString [Java-API],您知道程序打印的最短小數部分足以區分其最近鄰居的雙精度值 ,並在小數點前後至少有一位數字。

檢查約書亞布洛赫的Java的謎題:陷阱,陷阱,和極端情況 - 難題2:改變的時候了。他在那一章中解釋了這個問題。

3

原因是浮點計算的數字機制。 也當java試圖打印一個浮點值時,它會截斷尾隨零。 而且,你知道,類型使用8字節和浮動使用4.所以的預測是更大。

所以,當java計算你的浮點值時,它會得到類似於1.3497400的東西,並在輸出前截斷它。 當java計算你的double值時,它會得到更多的數字,所以你會得到這樣的結果。

嘗試執行這個簡單的例子更好地理解:

public class Test { 
    public static void main(String[] args) { 
     float sum = 0; 
     for (int i = 1; i <= 10; i++) { 
      sum += 0.1; 
     } 
     System.out.println(sum); 
    } 
} 

public class Test { 
    public static void main(String[] args) { 
     double sum = 0; 
     for (int i = 1; i <= 10; i++) { 
      sum += 0.1; 
     } 
     System.out.println(sum); 
    } 
}