2017-07-14 83 views
0

我正在使用帶有HALF_UP舍入模式的DecimalFormat,並且我有一個escenery,其中的工作不正常,我不知道爲什麼。Java DecimalFormat HALF_UP舍入錯誤

DecimalFormat df = new DecimalFormat("#.##"); 
df.setRoundingMode(RoundingMode.HALF_UP); 
float tmp = (float) (0.5 * 1.05); 
df.format(tmp); 
float mul = Float.parseFloat(df.format(tmp)); 

變量值mul我希望有0.53的值,我收到了0.52的值。

我正在使用Java 1.8.0_131。

解決的最終代碼

BigDecimal mul = new BigDecimal(0.5).multiply(new igDecimal(1.05)); 
mul = mul.setScale(2, RoundingMode.HALF_UP); 
System.out.println(mul); 
+0

Thank you for your comment,but I round rounding as HALF_UP must works「Rounding mode to round to」nearest neighbor「,除非兩個鄰居是等距離的,在這種情況下,四捨五入。「[Oracle Documentation](https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html) –

+2

'float'和'double'無法精確地存儲值...請參閱:https ://stackoverflow.com/q/3413448/4899193 –

+0

This works' System.out.println(df.format(0.5 * 1.05));' - 當然雙打 –

回答

8

您正在使用float數據類型。

此數據類型無法精確保持值0.525。看到這個代碼,這就很清楚:

float value = (float) (0.5 * 1.05); 
DecimalFormat df = new DecimalFormat("#.########################"); 
System.out.println(df.format(value)); 

此打印出:

0.5249999761581421

舍入這樣一個值與模式RoundingMode.HALF_UP正確產量0.52

double價值似乎能夠精確存儲值0.525

double value = 0.5 * 1.05; 
DecimalFormat df = new DecimalFormat("#.########################"); 
System.out.println(df.format(value)); 

這將打印的預期值:

0.525

舍入值與RoundingMode.HALF_UP模式現在將產生0.53

注意:即使是double數據類型也不會精確地存儲該值!

看@ MarkDickinson的評論。存儲值爲0.52500000000000002220446049250313080847263336181640625,該值恰好大於0.525,並且只是偶然發生了預期值。

那該怎麼辦?

數據類型floatdouble是基於二進制的,而我們人類在處理數字時傾向於認爲基於小數。閱讀文章"What Every Computer Scientist Should Know About Floating-Point Arithmetic"瞭解更多信息。

解決方法是使用基於十進制的數據類型,它存在於BigDecimal中。

+0

這個答案是有誤導性的,'double'不能精確地存儲'0.525'的值:它存儲的是'0.52500000000000002220446049250313080847263336181640625',因爲這個值只是_happens_高於'0.525',它向上舍入。 0.7 * 1.05',你會發現它是舍入而不是up.OP如果正確舍入_decimal_ halfway的情況下,他們需要使用一個十進制基於數字的類型。 –

+0

謝謝您的快速回復,但我的四捨五入繼續發生錯誤: 'double tmp = 0.5 * 1.05; DecimalFormat df = new DecimalFormat(「#。##」); df.setRoundingMode(RoundingMode.HALF_UP); System.out.println(df.format(tmp));' Thats returns 1.52 –

+0

@MarkDickinson感謝您的發現。我不知何故錯過了它。改變了我的答案。 – Seelenvirtuose