java - 甚至了解一半?

标签 java groovy rounding

当我打印时

(new BigDecimal(5) * new BigDecimal(0.049))​

它给出了

0.24500000000000000943689570931383059360086917877197265625

当我使用 ROUND_HALF_EVEN 将其舍入时

(new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN)​

打印

0.25

所以我的困惑是,它不应该四舍五入到偶数吗?所以不应该是 0.25,而是 0.24。请帮助解决这个困惑。谢谢!

最佳答案

这里真正的问题是您为 BigDecimal 使用了错误的构造函数。

(new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN)​

会做你想做的事。

问题是 0.049 是一个浮点文字,并且该值不能完全表示为浮点值(floatdouble 都不是),从而引入了一个微小的错误,在这种情况下是有意义的。

通过使用接受String参数的构造函数,您可以避免通过浮点进行转换并获得您想要的确切值。

由于精度有限,计算机上的浮点运算充满了令人讨厌的意外行为。如果您想了解有关陷阱的更多信息,请阅读 What Every Computer Scientist Should Know About Floating-Point Arithmetic

示例:

public static void main(String[] args) {
    BigDecimal result1 = (new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    BigDecimal result2 = (new BigDecimal(5).multiply(new BigDecimal(0.049))).setScale(2, BigDecimal.ROUND_HALF_EVEN);
    System.out.println(result1);
    System.out.println(result2);
}

打印

0.24
0.25

关于java - 甚至了解一半?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47507602/

相关文章:

java - 在 Java 中舍入 .5

java - double 被四舍五入而不精确

javascript - 数学四分之一

java - 如何解释 Java 线程堆栈?

java - 获取实现给定接口(interface)的所有类

java - 添加对 JSON 结构的更改

java - 创建 BitSet 时是否可以设置位?

grails generated-all '*' 创建损坏的 Controller 测试?脚手架生成是否已损坏?

jenkins - 如何使用 Groovy 动态构建 Jenkins 管道输入参数?

grails - 获取文件列表