我正在格式化一个十进制数字,我有以下标准来格式化它:
- 数字最多应为小数点后两位(10.1234=>10.12)
- 如果小数后只有一位数字,则它将以额外的0结束(10.5=>10.50)
- 千位分隔符将是逗号(1234.2345=>12345.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
?
问题是,首先不能将111111111111110.567表示为double
。(你甚至不能准确地表示你的最短值,但随着幅度的增加,误差会显著增加。)
无论如何,double
只有大约17个有效数字的有用数据——你试图得到22个数字。
如果你想要更高的精度,请使用BigDecimal
,但要注意这也会改变其他事情。无论如何,你试图代表什么样的价值观?自然值(权重、距离等)适用于double
;人工值(特别是货币值)适用于CCD_ 7。
我设法得到了这个(你必须使用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
资源链接:DecimalFormat
和BigDecimal
还有一件事,你必须输入BigDecimal数字作为String
,否则会引起问题。
BigDecimal x = new BigDecimal(1111111111111111110.567) will output the following.
1,111,111,111,111,111,168.00