看起来BigDecimal.setScale会截断到小数点+1的小数位,然后仅基于该小数舍入。
这是正常现象还是有一种干净的方法将舍入模式应用于每个小数?
输出为:0.0697
(这不是他们在学校教我的四舍五入模式)
double d = 0.06974999999;
BigDecimal bd = BigDecimal.valueOf(d);
bd = bd.setScale(4, RoundingMode.HALF_UP);
System.out.println(bd);
输出为:0.0698
(这是他们在学校教我的取整模式)
double d = 0.0697444445;
BigDecimal bd = BigDecimal.valueOf(d);
int scale = bd.scale();
while (4 < scale) {
bd = bd.setScale(--scale, RoundingMode.HALF_UP);
}
System.out.println(bd);
已编辑
阅读了一些答案后,我意识到我搞砸了一切。当我写问题时,我有点沮丧。
因此,我将重写问题原因,即使答案对我有很大帮助,但我仍然需要一些建议。
问题是:
我需要将0.06974999999舍入为0.0698,这是因为我知道实际上许多小数应为0.6975(在不受我控制的地方出现舍入误差)。
因此,我一直在尝试一种“双舍入”方法,该方法通过两个步骤执行舍入操作:首先舍入到更高的精度,然后舍入到所需的精度。
(这是我搞砸的地方,因为我认为每个小数位的循环都会更安全)。
问题是,我不知道第一步要舍入到哪个更高的精度(我使用的是小数位数-1)。另外,我不知道在其他情况下是否能找到一些意想不到的结果。
这是我放弃使用循环的第一种方法,在阅读您的答案后,现在看起来好得多:
public static BigDecimal getBigDecimal(double value, int decimals) {
BigDecimal bd = BigDecimal.valueOf(value);
int scale = bd.scale();
if (scale - decimals > 1) {
bd = bd.setScale(scale - 1, RoundingMode.HALF_UP);
}
return bd.setScale(decimals, roundingMode.HALF_UP);
}
这些打印以下结果:
0.0697444445 = 0.0697
0.0697499994 = 0.0697
0.0697499995 = 0.0698
0.0697499999 = 0.0698
0.0697444445 = 0.069744445 //舍入到9位小数
0.0697499999 = 0.069750000 //舍入到9位小数
0.069749 = 0.0698
现在的问题是,是否有更好的方法(可能是不同的舍入模式)?是否可以安全地用作一般的舍入方法?
我需要舍入许多值,并且必须在运行时根据我收到的数字的种类在此方法和标准方法之间进行选择,这似乎非常复杂。
感谢你的宝贵时间。
最佳答案
在四舍五入时,您将查看四舍五入到最后一位数字之后的值,在第一个示例中,您将0.06974999999舍入到小数点后四位。因此您有0.0697,然后是4999999(或基本上是697.4999999)。由于舍入模式为HALF_UP,因此0.499999小于0.5,因此将其舍入。