这是使用BigDecimals进行舍入的正确行为吗?

问题描述 投票:1回答:3

我试图像这样围绕BigDecimals:5.46597 - > 5.46,我认为下面的代码为我做了这个,但没有。

我用BigDecimal.round和BigDecimal.setScale尝试了它。

BigDecimal bD = new BigDecimal(5.46597); // whole number: 5.4659700000000004393996277940459549427032470703125 
bD.setScale(2, RoundingMode.HALF_DOWN); // 5.47
bD.round(new MathContext(3, RoundingMode.HALF_DOWN)); // 5.47

这不应该是5.46,或者我误解了什么?

java rounding scale bigdecimal
3个回答
10
投票

当实际值恰好在两个可能的舍入值之间的中途时,HALF_DOWN仅向下舍入。即5.46500 - > 5.46。另一方面5.4650000001 - > 5.47因为它比5.46更接近5.47。

也许你正在寻找的是RoundingMode.DOWN,它总是向下舍入。


4
投票

使用BigDecimal舍入ROUND_HALF_DOWN在JavaDoc中被定义为“ROUND_HALF_DOWN - 舍入模式以向”最近邻居“舍入,除非两个邻居都是等距的,在这种情况下向下舍入。 Documentation ROUND_HALF_DOWN Documentation RoundingMode.HALF_DOWN

对于BigDecimal.valueOf("5.46597").setScale(2, BigDecimal.ROUND_HALF_DOWN),最近的邻居是5.465.47,距离为0.005970.00403。所以到5.47的距离比5.46更小(更近),导致向5.47四舍五入。


2
投票

首先:使用带有double值的构造函数,立即引入每个浮点的近似误差。

运用

BigDecimal bD = new BigDecimal("5.46597");
bD = bD.setScale(2, RoundingMode.HALF_DOWN); // 5.47

BigDecimal bD = new BigDecimal("5.46500");
bD = bD.setScale(2, RoundingMode.HALF_DOWN); // 5.46

一个得到一个精确的固定点数与5位小数。

HALF_DOWN在.500000上向下舍入......没有任何分数,只有5er边界。

逻辑舍入将发生在其最接近的整数,超过一半将被四舍五入,低于一半将圆舍入。在国际数学标准的确切一半上说:向上舍入,但逻辑上(相同的距离)可以是:HALF_UP或HALF_DOWN。由于效果仅与精确的一半有关,因此不应使用双构造函数进行测试,这可能会产生一个略高于或低于精确一半的值。

你也忘记了作业。

© www.soinside.com 2019 - 2024. All rights reserved.