BigDecimal 精度保留RoundingMode

本文详细介绍了Java中BigDecimal类的精度保留方法,并通过实例展示了RoundingMode的不同取值方式及其对应的效果,包括常见的四舍五入及特殊场景下的舍入规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BigDecimal的精度保留

RoundingMode的几种取值方式(demo中默认保留两位)

roundingModeRoundingMode取值方式demo
0ROUND_UP直接丢掉保留位数后面的,保留位数最后一个数加1。(负号不参与计算)9.284->9.29;
-5.326->-5.33
1ROUND_DOWN直接丢掉保留位数后面的9.284->9.28;
-5.326->-5.32
2ROUND_CEILING如果是正数用UP规则,负数用DOWN规则9.284->9.29;
-5.326->-5.32
3ROUND_FLOOR如果是正数用DOWN规则,负数用UP规则9.284->9.28;
-5.326->-5.33
4ROUND_HALF_UP(>=5)四舍五入9.235->9.24;
-5.326->-5.33
5ROUND_HALF_DOWN(>5)五舍六入9.235->9.23;
-5.326->5.33
6ROUND_HALF_EVEN四舍六入五留双(银行家舍入),如果是5的则看前一奇偶,奇加偶舍9.235->9.24;
9.265->9.26;
7ROUND_UNNECESSARY断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException9.23->9.23;9.231->ArithmeticException
### JavaBigDecimal 处理精度和舍入问题 #### 使用字符串构造器创建 `BigDecimal` 直接通过浮点数来构建 `BigDecimal` 可能会因为二进制表示的固有局限而引入误差。为了确保数值被精确无误地记录下来,推荐使用基于字符串的构造方法。 ```java // 不建议的方式:可能导致意外的结果 BigDecimal incorrect = new BigDecimal(12.555); // 推荐方式:避免因浮点数转换造成的潜在错误 BigDecimal correct = new BigDecimal("12.555"); ``` 这种方式可以防止由于计算机内部存储机制导致的小数部分失真现象[^3]。 #### 设置比例尺并指定舍入模式 当需要调整小数位数时,可以通过调用 `setScale()` 方法,并传入期望保留的小数位以及所采用的具体舍入策略来进行操作: ```java // 设定保留两位小数,并应用半偶舍入规则 BigDecimal roundedValue = correct.setScale(2, RoundingMode.HALF_EVEN); System.out.println(roundedValue.toString()); ``` 这里选择了 `RoundingMode.HALF_EVEN`(银行家舍入),它是一种广泛接受的标准,在统计学上具有更好的准确性;当然也可以根据实际需求选用其他类型的舍入模式,比如 `HALF_UP` 或者 `CEILING` 等[^2]。 #### 完整示例代码展示 下面给出一段完整的程序片段用于说明上述要点的应用场景: ```java import java.math.BigDecimal; import java.math.RoundingMode; public class PrecisionExample { public static void main(String[] args) { // 正确初始化 BigDecimal 对象 BigDecimal valueA = new BigDecimal("12.555"); // 执行四舍五入到两位小数的操作 BigDecimal resultA = valueA.setScale(2, RoundingMode.HALF_EVEN); System.out.println("原始值:" + valueA.toPlainString() + " | 经过处理后的结果:" + resultA.toPlainString()); // 测试不同输入情况下的表现一致性 testPrecision(new BigDecimal("12.555")); testPrecision(new BigDecimal("12.5550000")); testPrecision(new BigDecimal("12.55500001")); } private static void testPrecision(BigDecimal num){ String originalStr = num.stripTrailingZeros().toPlainString(); BigDecimal processedNum = num.setScale(2,RoundingMode.HALF_EVEN).stripTrailingZeros(); System.out.printf("原--%s---------处理结果--> %s%n",originalStr ,processedNum ); } } ``` 这段代码不仅展示了如何正确地实例化 `BigDecimal` 和执行舍入逻辑,还提供了一个简单的测试函数来验证对于各种形式的数据都能得到一致性的处理效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值