奇怪的浮动除法结果

我发生在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中的float分区给了我一个Double,这是正确的,但为什么Double toString()给我一个如此奇怪的值“-129.99999813735482”而不是正确的“-130.0”?

正如大家所说的那样, doublefloat对于你想要做的事情来说不够精确。

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

 def money = -1.30 def r = 0.01 println ((money/r).class.name) println ((money/r).floatValue()) println ((money/r).toString() ) 

如您所见, Groovy使用BigDecimal ,这意味着输出为:

 java.math.BigDecimal -130.0 -130 

从浮点指南 :

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

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

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

具体而言, float不能精确地表示1.3和0.01。

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

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