Groovy vs Java - 浮点精度的差异
Groovy vs Java - difference in floating point accuracy
此处浮点精度差异的原因可能是什么?
def "emi test"(){
given:
def P = 6000000.00
def n = 20 * 12
def r = (8.35/12)/100
double emi_g = (P * r * (1+r).power(n)) / ((1+r).power(n) - 1)
double emi_j= (P * r * Math.pow(1+r,n)) / (Math.pow(1+r,n)-1);
expect:
emi_g == emi_j
}
结果:
emi_g == emi_j
| | |
| | 51501.177737160346
| false
51501.177737160666
不同之处在于结果的数据类型。
当 运行 在 shell 时,您的结果类型是:
groovy:000> emi_g.getClass()
===> class java.math.BigDecimal
groovy:000> emi_j.getClass()
===> class java.lang.Double
Groovy的实现returns一个BigDecimal
,比Double
有更好的精度
问题与类型有关。
(1 + r).power(n) - 1
的计算结果为 BigDecimal
P * r * (1 + r).power(n)
的计算结果为 BigDecimal
P * r * Math.pow(1 + r, n)
的计算结果为 Double
Math.pow(1 + r, n) - 1
的计算结果为 Double
目前尚不清楚您的要求是什么以及您是否关心丢失的精度,了解这些要求将有助于描述如何获得所需的行为。所问问题的答案...
What could be the reason for difference in floating point accuracy
here?
是因为表达式求值的类型不同,并且与 Double
除以 Double
相关的规则(事实上你是分子和分母值在 Double
开始,而不是 BigDecimial
) 导致你失去一些精度。
此处浮点精度差异的原因可能是什么?
def "emi test"(){
given:
def P = 6000000.00
def n = 20 * 12
def r = (8.35/12)/100
double emi_g = (P * r * (1+r).power(n)) / ((1+r).power(n) - 1)
double emi_j= (P * r * Math.pow(1+r,n)) / (Math.pow(1+r,n)-1);
expect:
emi_g == emi_j
}
结果:
emi_g == emi_j
| | |
| | 51501.177737160346
| false
51501.177737160666
不同之处在于结果的数据类型。
当 运行 在 shell 时,您的结果类型是:
groovy:000> emi_g.getClass()
===> class java.math.BigDecimal
groovy:000> emi_j.getClass()
===> class java.lang.Double
Groovy的实现returns一个BigDecimal
,比Double
问题与类型有关。
(1 + r).power(n) - 1
的计算结果为 BigDecimal
P * r * (1 + r).power(n)
的计算结果为 BigDecimal
P * r * Math.pow(1 + r, n)
的计算结果为 Double
Math.pow(1 + r, n) - 1
的计算结果为 Double
目前尚不清楚您的要求是什么以及您是否关心丢失的精度,了解这些要求将有助于描述如何获得所需的行为。所问问题的答案...
What could be the reason for difference in floating point accuracy here?
是因为表达式求值的类型不同,并且与 Double
除以 Double
相关的规则(事实上你是分子和分母值在 Double
开始,而不是 BigDecimial
) 导致你失去一些精度。