理解圆半甚至?

kof*_*rts 1 java groovy rounding

当我打印

(new BigDecimal(5) * new BigDecimal(0.049))?
Run Code Online (Sandbox Code Playgroud)

它给

0.24500000000000000943689570931383059360086917877197265625
Run Code Online (Sandbox Code Playgroud)

当我使用ROUND_HALF_EVEN围绕它

(new BigDecimal(5) * new BigDecimal(0.049)).setScale(2, BigDecimal.ROUND_HALF_EVEN)?
Run Code Online (Sandbox Code Playgroud)

它打印

0.25
Run Code Online (Sandbox Code Playgroud)

所以我的困惑是,它不应该舍入到偶数,所以代替0.25不应该是0.24.请帮助解决这个困惑.谢谢!

Jim*_*son 8

这里的REAL问题是你使用了错误的构造函数BigDecimal.

(new BigDecimal(5).multiply(new BigDecimal("0.049"))).setScale(2, BigDecimal.ROUND_HALF_EVEN)?
Run Code Online (Sandbox Code Playgroud)

会做你想做的.

问题是它0.049是一个浮点文字,并且该值不能完全表示为浮点值(既不是float也不是double),引入了一个微小的错误,在这种情况下是有意义的.

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

由于精度有限,计算机上的浮点运算充满了令人讨厌的意外行为.如果您想了解有关陷阱的更多信息,请阅读 每个计算机科学家应该知道的关于浮点运算的内容


Era*_*ran 6

int java.math.BigDecimal.ROUND_HALF_EVEN : 6 [0x6]

舍入模式向“最近邻居”舍入,除非两个邻居等距,在这种情况下,向偶数邻居舍入。

0.245000000000000009436895709313830593600869178771972656250.25比更接近0.24。仅当与两个邻居的距离相等时才选择偶数邻居(即,如果您试图四舍五入0.245)。

BigDecimal bd = new BigDecimal("0.245").setScale(2, BigDecimal.ROUND_HALF_EVEN);
System.out.println (bd);
Run Code Online (Sandbox Code Playgroud)

将打印0.24