Java中的BigDecimal应用

在工作中经常会遇到对金额的处理,这里整理下关于Decimal的数据进位方法

RoundingMode.UP 

定义:远离零方向舍入。

解释:始终对非零舍弃部分前面的数字加 1。注意,此舍入模式始终不会减少计算值的绝对值。

1  BigDecimal data1=new BigDecimal("2.225").setScale(2,RoundingMode.UP);
2  System.out.println("RoundingMode.UP:"+data1);
3  运行结果:RoundingMode.UP:2.23
4      
5  BigDecimal data1=new BigDecimal("2.222").setScale(2,RoundingMode.UP);
6  System.out.println("RoundingMode.UP:"+data1);
7  运行结果:RoundingMode.UP:2.23

 

RoundingMode.DOWN

定义:向零方向舍入

解释:从不对舍弃部分前面的数字加 1(即截尾)。注意,此舍入模式始终不会增加计算值的绝对值。

1 BigDecimal data=new BigDecimal("2.222").setScale(2, RoundingMode.DOWN);
2  System.out.println("RoundingMode.DOWN:"+data);
3  运行结果:RoundingMode.DOWN:2.22
4      
5  BigDecimal data=new BigDecimal("2.225").setScale(2, RoundingMode.DOWN);
6  System.out.println("RoundingMode.DOWN:"+data);
7  运行结果:RoundingMode.DOWN:2.22

RoundingMode.CEILING 

定义:向正无限大方向舍入。

解释:如果结果为正,则舍入行为类似于 RoundingMode.UP;如果结果为负,则舍入行为类似于RoundingMode.DOWN。注意,此舍入模式始终不会减少计算值。

1 BigDecimal data2=new BigDecimal("2.222").setScale(2,RoundingMode.CEILING);
2 System.out.println("RoundingMode.CEILING:"+data2);
3 运行结果:RoundingMode.CEILING:2.23
4     
5 BigDecimal data2=new BigDecimal("2.225").setScale(2,RoundingMode.CEILING);
6 System.out.println("RoundingMode.CEILING:"+data2);
7 运行结果:RoundingMode.CEILING:2.23           
8  

 

RoundingMode.FLOOR 

定义:向负无限大方向舍入。

解释:如果结果为正,则舍入行为类似于 RoundingMode.DOWN;如果结果为负,则舍入行为类似于RoundingMode.UP。注意,此舍入模式始终不会增加计算值。

1  BigDecimal data3=new BigDecimal("2.222").setScale(2,RoundingMode.FLOOR);
2  System.out.println("RoundingMode.FLOOR:"+data3);
3  运行结果:RoundingMode.FLOOR:2.22
4   
5  BigDecimal data3=new BigDecimal("2.225").setScale(2,RoundingMode.FLOOR);
6  System.out.println("RoundingMode.FLOOR:"+data3);
7  运行结果:RoundingMode.FLOOR:2.22

 

 

RoundingMode.HALF_UP

​ 定义:向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向上舍入。

​ 解释:如果被舍弃部分 >= 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN。注意,此舍入模式就是通常学校里讲的四舍五入。

 1  BigDecimal data4=new BigDecimal("2.222").setScale(2,RoundingMode.HALF_UP);
 2   System.out.println("RoundingMode.HALF_UP:"+data4);
 3   运行结果:RoundingMode.HALF_UP:2.22
 4   
 5   BigDecimal data4=new BigDecimal("2.226").setScale(2,RoundingMode.HALF_UP);
 6   System.out.println("RoundingMode.HALF_UP:"+data4);
 7   运行结果:RoundingMode.HALF_UP:2.23
 8       
 9   BigDecimal data4=new BigDecimal("2.225").setScale(2,RoundingMode.HALF_UP);
10   System.out.println("RoundingMode.HALF_UP:"+data4);
11   运行结果:RoundingMode.HALF_UP:2.23

 

RoundingMode.HALF_DOWN

定义:向最接近的数字方向舍入,如果与两个相邻数字的距离相等,则向下舍入。

解释:如果被舍弃部分 > 0.5,则舍入行为同 RoundingMode.UP;否则舍入行为同RoundingMode.DOWN。注意,此舍入模式就是通常讲的五舍六入。

 1  BigDecimal data5=new BigDecimal("2.222").setScale(2,RoundingMode.HALF_DOWN);
 2   System.out.println("RoundingMode.HALF_DOWN:"+data5);
 3   运行结果:RoundingMode.HALF_DOWN:2.22
 4   
 5   BigDecimal data5=new BigDecimal("2.226").setScale(2,RoundingMode.HALF_DOWN);
 6   System.out.println("RoundingMode.HALF_DOWN:"+data5);
 7   运行结果:RoundingMode.HALF_DOWN:2.23
 8       
 9   BigDecimal data5=new BigDecimal("2.225").setScale(2,RoundingMode.HALF_DOWN);
10   System.out.println("RoundingMode.HALF_DOWN:"+data5);
11   运行结果:RoundingMode.HALF_DOWN:2.22

 

RoundingMode.HALF_EVEN 

定义:向最接近数字方向舍入,如果与两个相邻数字的距离相等,则向相邻的偶数舍入

解释:如果舍弃部分左边的数字为奇数,则舍入行为同 RoundingMode.HALF_UP;如果为偶数,则舍入行为同RoundingMode.HALF_DOWN。注意,在重复进行一系列计算时,根据统计学,此舍入模式可以在统计上将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。此舍入模式类似于 Java 中对float 和double 算法使用的舍入策略。

银行家舍入法

银行家舍入法是由IEEE 754标准规定的浮点数取整算法 [1] ,大部分的编程软件都使用的是这种方法。 所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。其规则是:当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后不为空且非全0)时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后为空或全0)时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。

简单的说,就是:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一

 

 1 //舍去位!=5并且舍去的数<=4直接舍去
 2  BigDecimal data6=new BigDecimal("2.224").setScale(2,RoundingMode.HALF_EVEN);
 3  System.out.println("RoundingMode.HALF_EVEN:"+data6);
 4  运行结果:RoundingMode.HALF_EVEN:2.22
 5      
 6   //舍去位!=5并且舍去的数>=6直接进位
 7  BigDecimal data6=new BigDecimal("2.226").setScale(2,RoundingMode.HALF_EVEN);
 8  System.out.println("RoundingMode.HALF_EVEN:"+data6);
 9  运行结果:RoundingMode.HALF_EVEN:2.23
10      
11  //舍去位==5并且5后非空,直接进位
12  BigDecimal data6=new BigDecimal("2.2251").setScale(2,RoundingMode.HALF_EVEN);
13  System.out.println("RoundingMode.HALF_EVEN:"+data6);
14  运行结果:RoundingMode.HALF_EVEN:2.23 
15      
16  //舍去位==5并且5后为空,5前为偶,直接舍去
17  BigDecimal data6=new BigDecimal("2.225").setScale(2,RoundingMode.HALF_EVEN);
18  System.out.println("RoundingMode.HALF_EVEN:"+data6);
19  运行结果:RoundingMode.HALF_EVEN:2.22  
20      
21  //舍去位==5并且5后为空,5前为奇,直接进位
22  BigDecimal data6=new BigDecimal("2.235").setScale(2,RoundingMode.HALF_EVEN);
23  System.out.println("RoundingMode.HALF_EVEN:"+data6);
24  运行结果:RoundingMode.HALF_EVEN:2.24

 

RoundingMode.UNNECESSARY

定义:用于断言请求的操作具有精确结果,因此不发生舍入。

解释:计算结果是精确的,不需要舍入,否则抛出 ArithmeticException。

 

 

可以结合这篇文章一起阅读

https://my.oschina.net/sunchp/blog/670909

 

posted @ 2020-10-20 17:40  生命树gyh  阅读(349)  评论(0编辑  收藏  举报
© 2020 GitHub, Inc.