Java DecimalFormat 出錯了?

羅國榮 2016/08/19 10:00:00
2816

題: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的格式化結果不是預期中四捨五入的結果,難道是DecimalFormatBug

當然不是!

因為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

羅國榮