记录一次异常:Non-terminating decimal expansion; no exact representable decimal result

代码:

final BigDecimal bigDecimal = new BigDecimal("10.0");
     bigDecimal.divide(new BigDecimal("3.0"));

报错详细信息:

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    at java.math.BigDecimal.divide(BigDecimal.java:1693)

 

原因是 10 除以3  除不尽 时未指定舍未位规则 
当然 在可以除尽的时候 是不会报错的
新手就很容易犯错误    比如测试的时候使用除尽数字 如下:

final BigDecimal bigDecimal = new BigDecimal("10.0");
final BigDecimal divide = bigDecimal.divide(new BigDecimal("2.0"));

输出: 5

 

那么怎么指定舍未位规则呢   我们只需要增加 divide方法2个参数  保留小数位  和 规则 我下面使用的是 四舍五入规则 
 divide(new BigDecimal("3.0"), 2, RoundingMode.HALF_UP);

修改为: 

final BigDecimal bigDecimal = new BigDecimal("10.0");
final BigDecimal divide = bigDecimal.divide(new BigDecimal("3.0"), 2, RoundingMode.HALF_UP);
log.info("divide:{}", divide);

输出: 3.33

 

简单介绍下 RoundingMode 常用规则 以保留2为小数为例

 

RoundingMode.CEILING:等价于(BigDecimal.ROUND_CEILING)舍入模式向正无穷大舍入。如果结果是正的,则行为与RoundingMode.UP相同;如果为负,则行为与RoundingMode.DOWN相同。请注意,此舍入模式永远不会减少计算值

 

RoundingMode.DOWN:等价于(BigDecimal.ROUND_DOWN)舍入模式向零舍入。从不增加丢弃分数之前的数字(即截断)。请注意,这种舍入模式永远不会增加计算值的大小 3.339 ->3.33

 

RoundingMode.FLOOR:等价于(BigDecimal.ROUND_FLOOR)舍入模式向负无穷大舍入。如果结果是正的,则与RoundingMode.DOWN一样;如果为负,则表现与RoundingMode.UP相同。请注意,此舍入模式永远不会增加计算值

 

RoundingMode.HALF_DOWN:等价于(BigDecimal.ROUND_HALF_DOWN)五舍六入,舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下向下舍入。如果丢弃的分数 > 0.5,则行为与RoundingMode.UP相同;否则,行为与RoundingMode.DOWN相同

 

RoundingMode.HALF_UP:等价于(BigDecimal.ROUND_HALF_UP)四舍五入,舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下向上舍入。如果丢弃的分数 ≥ 0.5,则行为与RoundingMode.UP相同;否则,行为与RoundingMode.DOWN相同。请注意,这是学校通常教授的舍入模式

 

RoundingMode.HALF_EVEN:等价于(BigDecimal.ROUND_HALF_EVEN) 这个比较绕,整数位若是奇数则四舍五入,若是偶数则五舍六入  --舍入模式向“最近的邻居”舍入,除非两个邻居是等距的,在这种情况下,向偶数邻居舍入。如果丢弃的分数左边的数字是奇数,则表现与RoundingMode.HALF_UP相同;如果是偶数,其行为与RoundingMode.HALF_DOWN相同。请注意,这是一种舍入模式,当在一系列计算中重复应用时,可在统计上最小化累积误差。它有时被称为“银行家四舍五入”,主要用于美国。这种舍入模式类似于 Java 中用于float和double算术的舍入策略

 



 

posted @ 2022-07-18 17:20  loveCrane  阅读(198)  评论(0编辑  收藏  举报