2017-09-05 29 views
1

鑑於我們所知道的浮點精度,爲什麼這樣的代碼:爲什麼Java的捨本浮動

float a = 0.1f; 
System.out.println(a); 

打印0.1而不是0.100000001

+4

爲什麼*不應該*它? –

+0

維基是你的朋友在這裏https://en.wikipedia.org/wiki/Fixed-point_arithmetic – JJF

+0

因爲默認的格式化刪除了笑話數字。真的很可愛。請注意,您提供的數字不是確切的二進制浮點值。 – Bathsheba

回答

6

println(a)呼籲結束調用Float.toString(a),它說:

多少位必須打印爲一個小數部分?必須至少有一位數字才能表示小數部分,並且除此之外還需要多少位數,但只需要多少位數來唯一地區分參數值與類型爲float的相鄰值。也就是說,假設x是由該方法對有限非零參數產生的十進制表示法所表示的精確數學值,其值爲f。然後f必須是最接近xfloat值;或者,如果兩個float值同樣接近X,然後˚F必須是它們中的一個和的˚F有效數的至少顯著位必須爲0

或者所述另一種方式中,由於IEEE 754 single-precision floating-point值僅具有6至9 significant decimal digits精度,將不包括最後1,因爲它超過了存儲的數值的精度。

這裏是代碼顯示的數字:

System.out.println(Math.nextDown(0.1f)); // prints: 0.099999994 
System.out.println(0.1f);    // prints: 0.1 
System.out.printf("%.15f%n", 0.1f);  // prints: 0.100000001490116 
System.out.println(Math.nextUp(0.1f)); // prints: 0.10000001 
7

0.100000001不會確切無論是。如果你的Java是打印該浮動完全不圓脣,it would print

0.100000001490116119384765625 

這是無用的大多數浮點使用情況。

要麼它不完全輪迴,而且要得到0.100000001490116119384765625,要麼輪到它,而需要舍入策略。 The rounding strategy they picked用於在小數點後打印足夠的數字以區分浮點數和其他浮點值,並且最小爲一位數。這是不是必然足以區分浮動與其他價值。