• 180615-精度计算BigDecimal


    logo

    文章链接:https://liuyueyi.github.io/hexblog/2018/06/15/180615-精度计算BigDecimal/

    180615-精度计算BigDecimal

    目前接触的业务中,对数据的精度要求比较高,因此不再使用基本的float,double,改为用BigDecimal进行存储和相关的计算,端午前的这一篇博文,则简单的介绍下BigDecimal的使用姿势,早点回家早点放假

    I. 基本使用

    1. 构造方法

    几个常见的构造方式,将基本类型+String等,转换为BigDecimal对象

    public BigDecimal(char[] in);
    public BigDecimal(String val);
    public BigDecimal(BigInteger val);
    public BigDecimal(int val);
    public BigDecimal(long val);
    public BigDecimal(double val)
    

    2. 加减乘除

    public BigDecimal add(BigDecimal value);                        //加法
    
    public BigDecimal subtract(BigDecimal value);                   //减法 
    
    public BigDecimal multiply(BigDecimal value);                   //乘法
    
    public BigDecimal divide(BigDecimal value);                     //除法
    

    从上面的签名上,可以看出操作是属于链式结构(Builder模式),然后一个问题就是执行上面的操作之后,被调用的对象,是否会发生修改? (即下面的测试中的o值是否改变)

    @Test
    public void testBigDecimal() {
        BigDecimal o = new BigDecimal(11.1);
        BigDecimal d = new BigDecimal(1);
    
        System.out.println(o.add(d) + "| " + o);
    }
    

    输出结果

    12.0999999999999996447286321199499070644378662109375| 11.0999999999999996447286321199499070644378662109375
    

    结论: 计算后的结果需要保存,因为不会修改目标对象的值

    3. 精度

    前面的例子中,输出后面一长串,而这往往并不是我们希望的,所以可以设置下精度

    public BigDecimal setScale(int newScale, RoundingMode roundingMode);
    

    一个简单的case如下

    @Test
    public void testBigDecimal() {
        BigDecimal o = new BigDecimal(11.1);
        System.out.println(o.setScale(3, RoundingMode.CEILING) + "| " + o);
    }
    

    输出

    11.100| 11.0999999999999996447286321199499070644378662109375
    

    从上面的输出,特别是第二列,如果我们选择的精度方式是取下限,会不会有问题呢?

    @Test
    public void testBigDecimal() {
        BigDecimal o = new BigDecimal(11.1);
        System.out.println(o.setScale(1, RoundingMode.FLOOR) + "| " + o);
    }
    

    输出结果为:

    11.0| 11.0999999999999996447286321199499070644378662109375
    

    所以需要注意的地方就来了,对浮点数进行精度设置时,需要根据自己的业务场景,选择合适的取整方式,不然很容易出问题

    取精度的几个参数说明

    ROUND_CEILING    //向正无穷方向舍入
    ROUND_DOWN    //向零方向舍入
    ROUND_FLOOR    //向负无穷方向舍入
    ROUND_HALF_DOWN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
    ROUND_HALF_EVEN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
    ROUND_HALF_UP    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
    ROUND_UNNECESSARY    //计算结果是精确的,不需要舍入模式
    ROUND_UP    //向远离0的方向舍入
    

    II. 其他

    1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

    一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

    2. 声明

    尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

    3. 扫描关注

    blogInfoV2.png

  • 相关阅读:
    java语言基础1问题汇总
    java从命令行接受多个数字求和输出
    关于Django迁移出现问题
    python中在ubuntu中安装虚拟环境及环境配置
    MVC与MVT
    前端性能优化
    less、sass、stylus
    bootstrap
    Swiper4.x使用方法
    swiper
  • 原文地址:https://www.cnblogs.com/yihuihui/p/9188603.html
Copyright © 2020-2023  润新知