我试图从数据库中检索一些值并在 Groovy 脚本中使用它们以查找和比较差异。
一个例子如下(当我在定义和数据库中使用浮点值时,它们被定义为数字并且精度为 2),这就是输出的样子
>
通常通过查看这些值,我预计两者的差异都是 16,但事实并非如此。
关于我会错过什么的任何建议?
当数字以类型NUMBER(x,2)
或类似类型存储在数据库中时,这意味着您将获得小数点后 2 位的精确数值。通过将这些转换为浮点数,您将引入错误(一个小而有界的错误,但您已经发现了一个明显的错误),因为其中一些数字没有精确的表示。有些数字在转换为二进制时会无限重复,必须在某处截断。BigDecimal 准确地表示数字,只要您不通过传入浮点值来构造它们,在这种情况下,在涉及 BigDecimal 之前已经完成了损坏(此时它所能做的就是准确地表示浮点近似值的原始号码)。我认为使用 BigDecimal 是解决问题的简单方法。
由于它是一个 Groovy 脚本,我认为性能不是您最大的考虑因素,如果是(并且您担心通过实例化 BigDecimals 创建的所有垃圾),那么您可能会考虑 JB Nizet 建议的 delta 方法。(有关如何使用浮点数的一些指示,请参阅Peter Lawrey 的这篇文章。)但是 Java 的 GC 需要大量的临时对象,这通常不是最大的性能问题。
这里有一个关于浮点数与小数的问题,其中的答案描述了为什么浮点数不准确。