请有人帮助我使用java浮动。我观察到与java有些不一致 例如
Math.pow(10.0,-2)==0.01
Math.pow(10.0,-3)=0.0010 (instead of 0.001)
Math.pow(10.0,-4)=1.0 E-4
printf("%g",Math.pow(10,-4)) =0.000100000
而使用Python:
10**-1=0.1
10**-2=0.01
10**-3=0.001
使用Clojure 1.4
(Math/pow 10 -2) = 0.01
(Math/pow 10 -3) = 0.001
我的问题是,与Python相比,如何在Java中获得类似的结果 换句话说,如何在没有任何尾随零的情况下获得精确结果。为什么添加这些尾随零,是否有任何方法可以抑制它们。
答案 0 :(得分:5)
很容易解释尾随零的来源。
对于%g
,这很简单:%g
默认情况下始终显示6位有效数字,因此您会看到
1.00000
0.100000
0.0100000
0.00100000
0.000100000
1.00000e-5
1.00000e-6
...
您可以通过将精度设置为1个有效数字来摆脱它们,但您可能不希望这样,因为例如,它也会围绕2.5到3。
执行println
会直接显示Double.toString()
定义的结果(double
)的表示形式:
结果是一个字符串,表示参数的符号和大小(绝对值)。 [...]幅度 m :
[...]
如果 m 大于或等于10 -3 但小于10 7 ,那么它表示为整数部分 m ,十进制形式,没有前导零,后跟'。' ('\ u002E'),后跟一个或多个十进制数字,表示 m 的小数部分。
[...]
如果 m 小于10 -3 或大于或等于10 7 ,则表示为所谓的“计算机化的科学记数法。“设 n 是唯一的整数,使得10 n ≤ m &lt; 10 名词 1 ;然后让 a 成为 m 和10 n 的数学精确商,这样1≤ a < / em>&lt; 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
因为恰好是最接近10 -4 的double
的确切值。
如果您不想在BigDecimal
中完成所有数学计算,那么您可以使用%g
获得舍入结果的字符串表示(这使您有机会控制精度),从中创建一个BigDecimal
,并打印结果:
System.out.println(new BigDecimal( String.format("%g", Math.pow(10,-4) ) ).stripTrailingZeros());
答案 1 :(得分:0)
如果您的问题只是显示,可以使用DecimalFormat和'#'http://docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html