DecimalFormat - 格式化小数以保留可变数量的尾随零

DecimalFormat - Format decimal to preserve variable amount of trailing zeros

在使用 DecimalFormat 格式化为字符串时,我需要保留数字的小数位数,特别是尾随零。我需要使用 DecimalFormat,因为我还需要避免对大数使用科学记数法,如 here 所示,这是最好的方法。但是,正如您在 post 中看到的那样,提供的代码还删除了尾随零,而我想保留它们。

1.00 -> "1.00"
1.000 -> "1.000"

我见过很多涉及固定小数位数的问题,但在我的情况下,我需要考虑可变数量的小数位数。我研究了计算小数位数,但由于我的输入也可以是 Double(除了 BigDecimal 之外),似乎没有可靠的方法来计算所有数字的小数点后的数字。 Double.toString() 不起作用,因为 Doubles 会针对非常小和非常大的数字分解为指数表示法。有关为什么难以计算双精度数的小数位数的更多信息,请参阅 here

"Preserve" 尾随零?

一个double值不知道你想看到多少尾随零。只是一个,而1.001.000是同一个号,即1号。 无法用 double 值完成您的要求。

现在,BigDecimal 会记住尾随零的数量,所以如果你想打印一个 BigDecimal 值,保留数字的比例, 但确保它永远不会以科学计数法打印,不要使用 DecimalFormat,而是 使用 toPlainString():

Returns a string representation of this BigDecimal without an exponent field.


更新

如果您想打印一个 double 值,其中包含所需的小数位数(即没有尾随零),并希望确保它永远不会以科学记数法打印,请使用 DecimalFormat 非常高 MaximumIntegerDigits 和非常高 setMaximumFractionDigits.

"Very high" 表示值超出 double 的范围,因此 999 是一个很好的 "round" 数字,尽管 330 已经足够高了。

测试

DecimalFormat fmt = new DecimalFormat("0");
fmt.setMaximumIntegerDigits(330);
fmt.setMaximumFractionDigits(330);

System.out.println("0.0123400  = " + 0.0123400               + "   = " + fmt.format(0.0123400));
System.out.println("123400.00  = " + 123400.00                + "  = " + fmt.format(123400.00));
System.out.println("NaN        = " + Double.NaN          + "       = " + fmt.format(Double.NaN));
System.out.println("-INFINITY  = " + Double.NEGATIVE_INFINITY  + " = " + fmt.format(Double.NEGATIVE_INFINITY));
System.out.println("+INFINITY  = " + Double.POSITIVE_INFINITY + "  = " + fmt.format(Double.POSITIVE_INFINITY));
System.out.println("MIN_NORMAL = " + Double.MIN_NORMAL               + " = " + fmt.format(Double.MIN_NORMAL));
System.out.println("MIN_VALUE  = " + Double.MIN_VALUE + "                = " + fmt.format(Double.MIN_VALUE));
System.out.println("MAX_VALUE  = " + Double.MAX_VALUE               + "  = " + fmt.format(Double.MAX_VALUE));

输出

0.0123400  = 0.01234   = 0.01234
123400.00  = 123400.0  = 123400
NaN        = NaN       = �
-INFINITY  = -Infinity = -∞
+INFINITY  = Infinity  = ∞
MIN_NORMAL = 2.2250738585072014E-308 = 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072014
MIN_VALUE  = 4.9E-324                = 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049
MAX_VALUE  = 1.7976931348623157E308  = 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

或者 double(没有精度,总是近似值),或者 BigDecimal

使用 BigDecimal 作为 new BigDecimal("2.00") 定义两位数的正确比例(精度)。您可以通过编程方式设置比例。

对于数据库和计算(如财务)BigDecimal 很好。

BigDecimal.toPlainString()中可以避免输出的科学表示。

对于double,可以格式化为

s = String.format("%10.2f", 13.5789); // "   13.58"

所有这些都带有小数点,没有千位分隔符。

国际化(本地化)软件将使用 MessageFormat 和语言环境(明确或默认平台语言环境)。

Locale.setDefault(new Locale("bg", "BG"));
s = MessageFormat.format("Number: {0, number, #.##}, "
            + "amount: {1, number, currency}",
            42.125, 19.99);