Java BigDecimal不损失精度的方法
1、调用valueOf()方法(推荐)
2、调用构造方法BigDecimal(String)
Java BigDecimal的几种舍入模式
1、UP(BigDecimal.ROUND_UP)
- 向绝对值最大的方向舍入
- 只要舍弃位非0即进位
2、DOWN(BigDecimal.ROUND_DOWN)
- 向绝对值最小的方向输入
- 所有的位都舍弃,不存在进位情况。
3、CEILING(BigDecimal.ROUND_CEILING)
- 天花板数:正数变大,负数也是变大。即正得越多,负得越少。
- 正数,只要舍弃位非0即进位,同UP。负数,所有的位都舍弃,不存在进位情况,同DOWN。
- Math.round方法使用的即为此模式。
4、FLOOR(BigDecimal.ROUND_FLOOR)
- 地板数:正数变小,负数也是变小。即正得越少,负得越多。
- 正数,所有的位都舍弃,不存在进位情况,同DOWN。负数,只要舍弃位非0即进位,同UP。
5、HALF_UP(BigDecimal.ROUND_HALF_UP)
最近数字舍入(5舍)。经典的四舍五入,5是进位。
6、HALF_DOWN(BigDecimal.ROUND_HALF_DOWN)
最近数字舍入(5舍)。HALF_DOWN中5是舍弃不进位。
示例代码:
1 | // 5.5 |
7、HALF_EVEN(BigDecimal.ROUND_HALF_EVEN)
银行家算法。
四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。
8、UNNECESSARY(BigDecimal.ROUND_UNNECESSARY)
断言请求的操作具有精确的结果,因此不需要舍入。
如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。
示例代码:
1 | // 抛出ArithmeticException 只有1位小数时不会报错 |
Java BigDecimal不同模式下的舍入操作举例汇总
输入给定数字,保留1位数的结果如下:
输入数字 | UP | DOWN | CEILING | FLOOR | HALF_UP | HALF_DOWN |
---|---|---|---|---|---|---|
1.34 | 1.4 | 1.3 | 1.4 | 1.3 | 1.3 | 1.3 |
1.35 | 1.4 | 1.3 | 1.4 | 1.3 | 1.4 | 1.3 |
1.36 | 1.4 | 1.3 | 1.4 | 1.3 | 1.4 | 1.4 |
-1.34 | -1.4 | -1.3 | -1.3 | -1.4 | -1.3 | -1.3 |
-1.35 | -1.4 | -1.3 | -1.3 | -1.4 | -1.4 | -1.3 |
-1.351 | -1.4 | -1.3 | -1.3 | -1.4 | -1.4 | -1.4 |
-1.36 | -1.4 | -1.3 | -1.3 | -1.4 | -1.4 | -1.4 |
Java BigDecimal进行除法运算报异常
问题现象
执行下面的代码:
1 | BigDecimal sum = new BigDecimal("777.77"); |
报错:
1 | Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result. |
原因分析
BigDecimal进行除法运算时,准确的商可能是一个无限长的小数,如果此时没有指定舍入模式,就会报ArithmeticException。
上面的777.77除以15的结果是个无限循环小数,而没有指定舍入模式,所以报错。
解决方法
调divide(divisor, scale, roundingMode);方法,其中scale为保留位数,roundingMode为舍入模式。
1 | // 示例 |