Java 理解一半甚至一半?
当我打印时Java 理解一半甚至一半?,java,groovy,rounding,Java,Groovy,Rounding,当我打印时 (new BigDecimal(5) * new BigDecimal(0.049)) 它给 0.24500000000000000943689570931383059360086917877197265625 当我用圆形半偶数圆它的时候 (new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN) 它打印 0.25 所以我的困惑是,它不应该四舍五入到偶数,所以它不应
(new BigDecimal(5) * new BigDecimal(0.049))
它给
0.24500000000000000943689570931383059360086917877197265625
当我用圆形半偶数圆它的时候
(new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN)
它打印
0.25
所以我的困惑是,它不应该四舍五入到偶数,所以它不应该是0.25,而应该是0.24。请帮忙解决这个困惑。谢谢
int java.math.BigDecimal.ROUND\u HALF\u偶数:6[0x6]
舍入模式:向“最近的邻居”舍入,除非两个邻居距离相等,在这种情况下,向偶数邻居舍入
0.24500000000943689570931383059360086917877197265625
比0.24
更接近0.25
。如果与两个相邻点的距离相等,则仅选择偶数相邻点(即,如果您试图取整0.245
)
将打印
0.24
这里真正的问题是您对BigDecimal
使用了错误的构造函数
(new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN)
我会做你想做的
问题在于0.049
是一个浮点文本,并且该值不能精确地表示为浮点值(既不是float
也不是double
),引入了一个在这种情况下有意义的微小错误
通过使用接受字符串
参数的构造函数,可以避免通过浮点进行转换,并获得所需的精确值
由于精度有限,计算机上的浮点运算充满了令人讨厌的意外行为。如果你想了解更多关于陷阱的信息,请阅读
例如:
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
你真的打算从0.049开始吗?如果是,请使用新的BigDecimal(“0.049”)。这样,结果正好是0.245。在这一点上,你会看到
舍入到0.24,因为它在0.24和0.25之间。看来我需要报价。请给出答案。我接受它。Nit:0.049是一个双精度
,除非Groovy对浮点文本有不同的规则。我认为这是一个比这个问题的公认答案更好的答案,因为OP已经知道,当他使用带有非字符串参数的bigdecime
构造函数时,精度会丢失。这个答案还指出了BigDecimal.ROUND_HALF_偶数
的行为,这就是OP没有得到预期值的原因。
0.24
0.25