提问人:sameer59 提问时间:10/4/2023 最后编辑:sameer59 更新时间:10/4/2023 访问量:81
如何使用 BigDecimal 而不是 double 在 Java 中实现 Excel MROUND() 函数
How to implement Excel MROUND() function in Java using BigDecimal instead of double
问:
如何在 Java 中四舍五入到特定的倍数?在excel中,有mround函数,它允许轻松舍入到指定的倍数,如下所示:
mRound(variable,multiple)
例如,这就是 Java 函数在给定的“数字”和“因子”下应该如何工作。 要获得更多测试数据,只需在 MS Excel 中的“数字”和“因子”列下方添加,然后在下一列中使用 excel 内置的 MROUND 函数作为 =MROUND(Number, Factor)
我知道如何使用 double 来完成它,但是当我处理财务数据时,我需要一个 BigDecimal 的解决方案。
双 -
double mRound(double value, double factor) {
return Math.round(value / factor) * factor;
}
这就是excel MROUND函数的工作原理 -MROUND Excel 函数将数字四舍五入到所提供数字的最接近的倍数。您必须考虑 Excel 如何知道是向上舍入还是向下舍入。这取决于划分的结果。
例如 16 / 3 = 5.33333,这里的十进制值小于 0.5,因此数字 3 的最接近倍数的结果是 5,因此 3 * 5 = 15。在这里,如果十进制值小于 0.5,Excel 会向下舍入该值。
同样,看看这个等式 20 / 3 = 6.66667。在此等式中,十进制值大于 0.5,因此 Excel 将结果四舍五入为 7,因此 3 * 7 = 21。
有关 MROUND 工作原理的更多详细信息,请参阅 - https://www.wallstreetmojo.com/mround-in-excel/
答:
该类提供了所有需要的方法来执行相同的操作 - 舍入有点棘手,因为使用需要精度:总位数,而不是小数部分的位数。但可以替代 .BigDecimal
Math.round(value / factor) * factor;
BigDecimal#round
MathContext
BigDecimal#setScale
Math#round
假设两者都已经存在,我们将你的方法写成:values
factor
BigDecimal
static BigDecimal mRound(BigDecimal value, BigDecimal factor) {
return
value
.divide(factor)
.setScale(0, RoundingMode.HALF_UP)
.multiply(factor);
}
我相信 和 方法不需要更多解释,有关详细信息,请参阅 javadoc 的 。divde()
multiply()
BigDecimal
这些方法用于对数字进行舍入。如上所述:“刻度是小数点右边的位数。
我们使用了:setScale()
scale: 0
因为我们不需要十进制数字;roundingMode: HALF_UP
由于我们想要或更大范围再次四舍五
入,请参阅不同模式的文档。0.5
若要从结果中删除尾随零,请在乘法后使用以下方法:stripTrailingZeros()
return
...
.multiply(factor)
.stripTrailingZeros();
请注意,使用可能会导致问题,因为这不是一个确切的表示 - 请改用!
例如,结果为 .new BigDecimal(double)
double
new BigDecimal(String)
new BigDecimal(1.2)
1.1999999999999999555910790149937383830547332763671875
测试
List<List<BigDecimal>> data = """
523.235 0.05
523.265 0.05
523.205 0.05
523.735 0.05
523.785 0.05
523.75 0.05
523.705 0.05
15 8
17 5
523.235 0.01
523.265 0.01
523.205 0.01
523.735 0.01
523.785 0.01
523.75 0.01
523.705 0.01
"""
.lines()
.map(line -> Arrays.stream(line.split("\\h+")).map(BigDecimal::new).toList())
.toList();
for (var test : data) {
var value = test.get(0);
var factor = test.get(1);
var result = mRound(value, factor);
System.out.printf("%10s %5s %10s%n", value, factor, result);
}
结果
523.235 0.05 523.25
523.265 0.05 523.25
523.205 0.05 523.20
523.735 0.05 523.75
523.785 0.05 523.80
523.75 0.05 523.75
523.705 0.05 523.70
15 8 16
17 5 15
523.235 0.01 523.24
523.265 0.01 523.27
523.205 0.01 523.21
523.735 0.01 523.74
523.785 0.01 523.79
523.75 0.01 523.75
523.705 0.01 523.71
请注意,结果与给定的输入图像不匹配 - 我想知道这是否是 Excel 中的错误(它是否使用 ?523.785 0.01
double
评论