本文最后更新于:August 20, 2022 pm
积土成山,风雨兴焉;积水成渊,蛟龙生焉;积善成德,而神明自得,圣心备焉。故不积跬步,无以至千里,不积小流无以成江海。齐骥一跃,不能十步,驽马十驾,功不在舍。面对悬崖峭壁,一百年也看不出一条裂缝来,但用斧凿,能进一寸进一寸,能进一尺进一尺,不断积累,飞跃必来,突破随之。
目录
今天在使用大数BigDecimal时,出现了一个问题。先附上报错以及原因。
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
在用BigDecimal做除法的时候,遇到了不整除的情况,而且造成的结果是无限循环小数,就会抛出以上异常。
示例
| BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(2); System.out.println(b1.divide(b2));
|
| BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(4); System.out.println(b1.divide(b2));
|
| BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(3); System.out.println(b1.divide(b2));
java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
|
解决办法
只需要在 divide() 方法指定精度和舍入模式就可以解决该问题。
常量名 |
描述 |
ROUND_UP |
远离零方向舍入。向远离0的方向舍入,也就是说,向绝对值最大的方向舍入,只要舍弃位非0即进位。 |
ROUND_DOWN |
趋向0方向舍入。向0方向靠拢,也就是说,向绝对值最小的方向输入,注意:所有的位都舍弃,不存在进位情况。 |
ROUND_CEILING |
向正无穷方向舍入。向正最大方向靠拢,如果是正数,舍入行为类似于ROUND_UP;如果为负数,则舍入行为类似于ROUND_DOWN.注意:Math.round方法使用的即为此模式。 |
ROUND_FLOOR |
向负无穷方向舍入。向负无穷方向靠拢,如果是正数,则舍入行为类似ROUND_DOWN,如果是负数,舍入行为类似以ROUND_UP。 |
ROUND_HALF_UP |
最近数字舍入(5舍),这就是我们经典的四舍五入。 |
ROUND_HALF_DOWN |
最近数字舍入(5舍)。在四舍五入中,5是进位的,在HALF_DOWN中却是舍弃不进位。 |
ROUND_HALF_EVEN |
银行家算法。四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。 |
ROUND_UNNECESSARY |
断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。 |
舍入模式示例
示例一
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(3); System.out.println(10.0/3.0); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_CEILING)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_FLOOR)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_EVEN));
3.3333333333333335 ROUND_UP:3.4 ROUND_DOWN:3.3 ROUND_CEILING:3.4 ROUND_FLOOR:3.3 ROUND_HALF_UP:3.3 ROUND_HALF_DOWN:3.3 ROUND_HALF_EVEN:3.3
|
示例二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BigDecimal b1 = new BigDecimal(12345); BigDecimal b2 = new BigDecimal(1000); System.out.println(12345.0/1000.0); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_CEILING)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_FLOOR)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_EVEN));
12.345 ROUND_UP:12.4 ROUND_DOWN:12.3 ROUND_CEILING:12.4 ROUND_FLOOR:12.3 ROUND_HALF_UP:12.3 ROUND_HALF_DOWN:12.3 ROUND_HALF_EVEN:12.3
|
示例三
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BigDecimal b1 = new BigDecimal(12456); BigDecimal b2 = new BigDecimal(1000); System.out.println(12456.0/1000.0); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_CEILING)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_FLOOR)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_EVEN));
12.456 ROUND_UP:12.5 ROUND_DOWN:12.4 ROUND_CEILING:12.5 ROUND_FLOOR:12.4 ROUND_HALF_UP:12.5 ROUND_HALF_DOWN:12.5 ROUND_HALF_EVEN:12.5
|
示例四
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BigDecimal b1 = new BigDecimal(12567); BigDecimal b2 = new BigDecimal(1000); System.out.println(12567.0/1000.0); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_CEILING)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_FLOOR)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_UP)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_DOWN)); System.out.println(b1.divide(b2,1,BigDecimal.ROUND_HALF_EVEN));
12.567 ROUND_UP:12.6 ROUND_DOWN:12.5 ROUND_CEILING:12.6 ROUND_FLOOR:12.5 ROUND_HALF_UP:12.6 ROUND_HALF_DOWN:12.6 ROUND_HALF_EVEN:12.6
|