我在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”?
答案 0 :(得分:6)
为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而且 相反,我得到一个奇怪的结果,如0.30000000000000004?
因为在内部,计算机使用格式(二进制浮点) 它不能准确地表示0.1,0.2或0.3之类的数字。
编译或解释代码时,您的“0.1”已经存在 四舍五入到该格式的最接近的数字,这导致一个小的 甚至在计算发生之前就会出现舍入错误。
具体而言,1.3和0.01都不能用float
准确表示。
答案 1 :(得分:4)
正如大家所说,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 uses BigDecimal
,表示输出为:
java.math.BigDecimal
-130.0
-130
答案 2 :(得分:1)
通过执行floatValue
,您将限制值的精确度。因此,JVM进行舍入,您将获得不同的值。
之前你说“但130.0应该是计算出的值,因为它是正确的”请记住,计算机使用二进制格式来表示十进制数,这会导致分数的舍入错误(尝试用二进制表示0.3)理解为什么)。