奇怪的浮动除法结果
我发生在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”?
正如大家所说的那样, double
和float
对于你想要做的事情来说不够精确。
一种解决方案是不使用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以理解原因) 。