簡體   English   中英

文字與計算的浮點精度

[英]Floating point precision in literals vs calculations

我想知道為什么Java中的浮點數在初始化為文字時可以表示精確值,但是當它們表示某些計算結果時它們是近似值。 例如:

double num1 = 0.3;
double num2 = 0.1 + 0.2;
System.out.println(num1);
System.out.println(num2);

為什么結果是:

0.3
0.30000000000000004

並不是:

0.30000000000000004
0.30000000000000004

當沒有精確的二進制表示0.3。 我知道BigDecimal類,但我不太明白這個原始數字的不一致性。

這三個數字中沒有一個可以完全表示為double 您得到不同結果的原因是,添加0.10.2之后的值具有與0.3不同的表示誤差。 大約5.5E-17的差異足以在打印出結果( 演示 )時產生差異。

double a = 0.2;
double b = 0.1;
double c = 0.3;
double d = a+b;
double e = d-c; //  This is 5.551115123125783E-17

當0.3被轉換為其表示為1和0然后轉換回小數時,它將舍入為0.3。 但是,當0.1和0.2分別轉換為二進制時,誤差在加法時相加,以便在總和轉換回十進制時顯示。 詳盡的解釋將涉及演示每個數字的IEEE表示以及添加和轉換。 有點涉及,但我希望你有這個想法。

添加本身不能產生0.3的精確表示,因此打印0.1 + 0.2的結果產生0.30000000000000004

另一方面,當調用System.out.println(0.3); println(double)方法將對結果執行一些舍入:它最終調用Double.toString(double) ,它提到結果是近似的:

m或a的小數部分必須打印多少位? 必須至少有一個數字來表示小數部分,並且除此之外必須有多個,但只需要多少,更多的數字來唯一地區分參數值和double類型的相鄰值。 也就是說,假設x是由該方法為有限非零參數d生成的十進制表示所表示的精確數學值。 那么d必須是最接近x的double值; 或者如果兩個double值同樣接近x,則d必須是其中之一,d的有效位的最低有效位必須為0。

如果你使用BigDecimal ,可以看到差異:

System.out.println(0.3);  // 0.3
System.out.println(new BigDecimal(0.3));  // 0.299999999999999988897769753748434595763683319091796875

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM