2013-04-05 92 views
1

我试图从数据库中检索几个值,并在Groovy脚本中使用它们来查找和比较差异。Groovy号码比较问题

一个实例是如下(I在定义和在它们被定义为号码和与精度2数据库中使用的浮点值时),这是输出看起来如何

> 

通常通过观察值我希望这两个差异是16,但事实并非如此。

关于我会错过什么的建议?

+6

[什么每台计算机科学家应该知道关于浮点运算(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – 2013-04-05 13:55:19

+0

感谢您的答复,我岂可完全忽略浮点值并转移到其他东西? – Techie 2013-04-05 14:18:34

+3

如果你想得到确切的结果,那么使用整数算术或BigDecimal,是的。否则,在比较值时使用增量(例如,如果它们相差小于0.001,则认为它们相等) – 2013-04-05 14:20:38

回答

1

当您的数据库中存储的数字类型为NUMBER(x,2)或类似数字时,表示您在小数点后两位获得精确数值。通过将这些数据转换为浮点数,你引入了错误(一个小的和有界的错误,但是你已经发现了一个明显的错误),因为这些数字中没有一个确切的表示。转换为二进制时的一些数字是无限重复的,必须在某处被截断。 BigDecimal正好表示数字,只要您不通过传入浮点值来构造它们,在这种情况下,损坏在BigDecimal涉及之前就已经完成了(它在此时的所有操作都可以完全代表浮点近似的原始数字)。我认为使用BigDecimal是解决您的问题的简单方法。因为它是一个Groovy脚本,我假设性能不是你最大的考虑因素,如果它是(并且你关心通过实例化BigDecimals创建的所有垃圾),那么你可以考虑由JB Nizet提出的delta方法。 (有关如何使用浮点数的一些指示,请参阅this article by Peter Lawrey。)但是,Java的GC期望很多短暂对象,但这通常不是最大的性能问题。

有一个关于浮点数与小数点的问题here的答案描述了为什么浮点数不准确。