Java 使用半向上舍入模式舍入时BigDecimal的惊人行为

Java 使用半向上舍入模式舍入时BigDecimal的惊人行为,java,math,rounding,bigdecimal,Java,Math,Rounding,Bigdecimal,我正在从0.495的双精度值创建一个BigDecimal,并使用HALF_UP舍入模式将其打印为两个十进制数字。代码如下: BigDecimal d = new BigDecimal(0.495); d = d.setScale(2, BigDecimal.ROUND_HALF_UP); System.out.println(d.toPlainString()); 我预计结果是0.50,但我看到的是0.49=.5,则code>向上取整应向上取整。 那为什么我会看到这种行为呢?当你写作时 new

我正在从0.495的双精度值创建一个BigDecimal,并使用
HALF_UP
舍入模式将其打印为两个十进制数字。代码如下:

BigDecimal d = new BigDecimal(0.495);
d = d.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(d.toPlainString());
我预计结果是0.50,但我看到的是0.49<如果丢弃的分数
>=.5,则code>向上取整
应向上取整。

那为什么我会看到这种行为呢?

当你写作时

new BigDecimal(0.495)
您正在将一个
double
值传递给
BigDecimal
构造函数。双值是近似值。在本例中,您的
BigDecimal
实例的值从实例化点开始略低于
0.495

如果传递字符串而不是双精度,则
BigDecimal
将表示该字符串所指示的精确值

所以使用

BigDecimal d = new BigDecimal("0.495");

请记住,如果从双精度
0.495
开始,在
BigDecimal
被实例化之前,您已经在进行近似运算了。如果以“0.495”开头会怎么样?当你使用0.495时,实际上得到的是0.4949999999999999555910790149937383830547332763671875相关:换句话说,如果你想将bigdecim初始化为精确的十进制值,千万不要使用double。如果可以,请使用字符串。