1

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

  • 数字最多应保留两位小数(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

4

2 回答 2

3

问题是你不能double首先将 1111111111111111110.567 完全表示为 a 。(你甚至不能准确地表示你的最短值,但是随着幅度的增加,不准确性会显着增加。)

无论如何, Adouble只有大约 17 位有效数字的有用数据 - 你试图获得 22 位数字。

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

于 2013-08-20T08:43:41.660 回答
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
于 2013-08-20T08:53:10.780 回答