• 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

  • 相关阅读:
    ubuntu14.04通过将语音,耳机没有声音
    网络编程easy错误点-手知道
    如何实现网页在线咨询框架
    C++定义自己的命名空间和头文件
    使用光标
    工作日两个日期之间的数
    Swift
    Swift
    Swift
    Swift
  • 原文地址:https://www.cnblogs.com/LifeFruit/p/13847864.html
Copyright © 2020-2023  润新知