Java DecimalFormat 出錯了?
主 題:Java DecimalFormat 出錯了?
文章簡介:多了解一點DecimalFormat的浮點數格式化
作 者:羅國榮
產出日期: 2016.08.13
1 前言
自從JAVA有了DecimalFormat系列的Class之後,在處理數字轉成各種型式的字串時,提供方便、簡單、容易使用的Method。
因為太方便了,往往有了先入為主的念頭造成誤解,例如:對於浮點數格式化(format)的誤解。
2 目的
讓DecimalFormat正確處理浮點數的四捨五入。
3 說明
先來看一個將浮點數格式化為小數點二位數的簡單程式:
import java.text.DecimalFormat;
import java.text.DecimalFormat;
public class Test {
public static void main(String[] args) {
double d;
String s;
DecimalFormat DecimalFormat = new DecimalFormat("#.00");
// 格式化數字至小數點第二位,預期格式化會採用四捨五入處理
//=====
d = 99.154;
s = DecimalFormat.format(d); // 預期答案:99.15
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.15)正確
d = 99.155;
s = DecimalFormat.format(d); // 預期答案:99.16
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.16)正確
d = 99.156;
s = DecimalFormat.format(d); // 預期答案:99.16
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.16)正確
//=====
d = 99.144;
s = DecimalFormat.format(d); // 預期答案:99.14
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.14)正確
d = 99.145;
s = DecimalFormat.format(d); // 預期答案:99.15
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.14)不正確 訝異!!!!
d = 99.146;
s = DecimalFormat.format(d); // 預期答案:99.15
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.15)正確
}
}
從程式的執行結果發現99.145的格式化結果不是預期中四捨五入的結果,難道是DecimalFormat有Bug?
當然不是!
因為DecimalFormat預設的格式化方式不是採用四捨五入方式,必須指定格式化方式為四捨五入方式,才能得到預期的結果。
如何設定?請再看一個範例程式。
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class Test1 {
public static void main(String[] args) {
double d;
String s;
NumberFormat numberFormat = new DecimalFormat("#.00");
// 格式化數字至小數點第二位
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
//指定格式化採用四捨五入處理關鍵的設定
//=====
d = 99.144;
s = numberFormat.format(d); // 預期答案:99.14
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.14)正確
d = 99.145;
s = numberFormat.format(d); // 預期答案:99.15
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.15)正確 正確了!!!!
d = 99.146;
s = numberFormat.format(d); // 預期答案:99.15
System.out.println("number: " + d + " --> result: " + s);
// 結果(99.15)正確
}
}
進行RoundingMode設定後,DecimalFormat就能夠採用四捨五入進行格式化。
更多的資訊可以參考「4 參考來源」。
4 參考來源
DecimalFormat对数值格式化的舍入问题——RoundingMode
http://blog.csdn.net/alanzyy/article/details/8465098