奇怪的浮动除法结果

时间:2012-12-03 12:01:34

标签: java grails groovy floating-point

我在grails项目中发生了这个奇怪的除法错误(但我认为grails与它没什么关系,我认为是一个常规或java问题):

如果在groovy控制台中我运行

float money = -1.30
float r = 0.01

println ((money/r).class.name)
println ((money/r).floatValue())
println ((money/r).toString() )

我得到了这个输出

java.lang.Double
-130.0
-129.99999813735482

groovy中的浮动分区给了我一个Double,这是正确的但是 为什么Double toString()给我一个如此奇怪的值“-129.99999813735482”和 不是正确的“-130.0”?

3 个答案:

答案 0 :(得分:6)

来自Floating-Point Guide

  

为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而且   相反,我得到一个奇怪的结果,如0.30000000000000004?

     

因为在内部,计算机使用格式(二进制浮点)   它不能准确地表示0.1,0.2或0.3之类的数字。

     

编译或解释代码时,您的“0.1”已经存在   四舍五入到该格式的最接近的数字,这导致一个小的   甚至在计算发生之前就会出现舍入错误。

具体而言,1.3和0.01都不能用float准确表示。

答案 1 :(得分:4)

正如大家所说,doublefloat对于您正在尝试的内容不够精确。

一种解决方案是不使用float作为您的对象类型,并执行:

def money = -1.30
def r = 0.01

println ((money/r).class.name)
println ((money/r).floatValue())
println ((money/r).toString() )

如您所见,Groovy uses BigDecimal,表示输出为:

java.math.BigDecimal
-130.0
-130

答案 2 :(得分:1)

通过执行floatValue,您将限制值的精确度。因此,JVM进行舍入,您将获得不同的值。

之前你说“但130.0应该是计算出的值,因为它是正确的”请记住,计算机使用二进制格式来表示十进制数,这会导致分数的舍入错误(尝试用二进制表示0.3)理解为什么)。