很容易解释尾随零的来源。
因为%g
它很简单:%g
默认情况下总是显示 6 个有效数字,所以你会看到
1.00000
0.100000
0.0100000
0.00100000
0.000100000
1.00000e-5
1.00000e-6
...
您可以通过将精度设置为 1 个有效数字来消除它们,但您可能不想这样做,因为这也会将 2.5 舍入到 3,例如。
执行 aprintln
直接显示结果 (a double
) 的表示,如 定义Double.toString()
:
结果是一个字符串,表示参数的符号和大小(绝对值)。[...] 量级m:
[...]
如果m大于或等于 10 -3但小于 10 7,则表示为m的整数部分,以十进制形式表示,不带前导零,后跟“.”。('\u002E'),后跟一个或多个小数位,表示m的小数部分。
[...]
如果m小于 10 -3或大于或等于 10 7,则它以所谓的“计算机科学计数法”表示。令n为唯一整数,使得 10 n ≤ m < 10 n +1;然后让a是m和 10 n的数学精确商,使得 1 ≤ a < 10。然后将大小表示为 a 的整数部分,作为一个十进制数字,后跟“。” ('\u002E'),后跟表示 a 的小数部分的十进制数字,后跟字母 'E' ('\u0045'),后跟n表示为十进制整数,由方法 生成Integer.toString(int)
。
[...]
m或a的小数部分必须打印多少位?必须至少有一个数字来表示小数部分,除此之外,必须有尽可能多的数字,但只需要将参数值与相邻的 double 类型值唯一区分开来。
因此你看到
1.0
0.01
0.0010
1.0E-4
9.999999999999999E-6
1.0E-6
...
那么如何摆脱尾随零呢?
一种方法是使用BigDecimal
,它有一个stripTrailingZeros()
方法。但是你必须小心你如何使用它:
System.out.println(BigDecimal.TEN.pow( -4 ,MathContext.DECIMAL64).stripTrailingZeros());
将打印预期的
0.0001
但
System.out.println(new BigDecimal(Math.pow(10,-4)).stripTrailingZeros());
将打印
0.000100000000000000004792173602385929598312941379845142364501953125
因为这恰好double
是最接近 10 -4的确切值。
如果你不想在BigDecimal
s 中做所有的数学运算,那么你可以得到一个四舍五入结果的字符串表示形式%g
(这让你有机会控制精度),从中得出一个BigDecimal
结果,然后打印结果:
System.out.println(new BigDecimal( String.format("%g", Math.pow(10,-4) ) ).stripTrailingZeros());