格式化十进制数

时间:2013-08-20 08:41:01

标签: java decimal number-formatting decimalformat

我正在格式化一个十进制数字,我有以下标准来格式化它:

  • 数字最多应为小数点后两位( 10.1234 => 10.12
  • 如果小数点后只有一位数字,则会以额外的0结尾( 10.5 => 10.50
  • 千位分隔符将为逗号( 12345.2345 => 12,345.23

我写了以下逻辑:

double x = Double.parseDouble(value.toString());
String dec = x % 1 == 0 ?  new java.text.DecimalFormat("###,###.##").format(x) : new java.text.DecimalFormat("###,###.00").format(x);

现在正在打印:

11111111111110.567=>11,111,111,111,110.57
111111111111110.567=>111,111,111,111,110.56
1111111111111110.567=>1,111,111,111,111,110.60
11111111111111110.567=>11,111,111,111,111,110
111111111111111110.567=>111,111,111,111,111,104
1111111111111111110.567=>1,111,111,111,111,111,170

我不明白为什么行为会发生变化。我应该如何将1111111111111111110.567打印为1,111,111,111,111,111,110.57

2 个答案:

答案 0 :(得分:3)

问题在于,您无法将1111111111111111110.567完全表示为double。 (你甚至不能代表你的最短值完全,但随着你增加幅度,不准确性会显着增加。)

A double只有大约17个有用数据的有效数字 - 你试图获得22位数字。

如果您想要更高精度,请使用BigDecimal - 但请注意,这也会改变其他方面。无论如何,你想要代表什么样的价值?自然值(权重,距离等)适用于double;人工价值(特别是货币价值)适用于BigDecimal

答案 1 :(得分:3)

我设法得到了这个(你必须使用BigDecimal):

import java.math.BigDecimal;
import java.text.NumberFormat;

public class Sandbox {
    public static void main(String[] args) {
        BigDecimal x = new BigDecimal("1111111111111111110.567");
        DecimalFormat formatter = new DecimalFormat("###,###.00");
        System.out.println(formatter.format(x));
    }
}

输出:

1,111,111,111,111,111,110.57

资源链接:DecimalFormatBigDecimal

还有一件事,你必须输入BigDecimal数字作为String,否则会导致问题。

BigDecimal x = new BigDecimal(1111111111111111110.567) will output the following.

1,111,111,111,111,111,168.00