1

我在一个 grails 项目中发生了这个奇怪的除法错误(但我认为 grails 与它无关,我认为是一个 groovy 或 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”?

4

3 回答 3

6

浮点指南

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

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

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

具体来说,1.3 和 0.01 都不能准确地用 a 表示float

于 2012-12-03T12:04:41.533 回答
5

正如每个人所说,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
于 2012-12-03T12:07:38.317 回答
1

通过执行floatValue,您限制了值的精确度。所以 JVM 进行了舍入,你得到了不同的值。

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

于 2012-12-03T12:06:05.607 回答