zoukankan      html  css  js  c++  java
  • 浮点数据精确计算之~BigDecimal

    一、概述

    在大多数情况下,浮点数类型float和double运算会丢失精度,计算的结果是准确的,float和double只能用来做科学计算或者是工程计算,Java在商业计算中要用 java.math.BigDecimal

    BigDecimal有多种构造函数,常用的有2种。建议使用String构造方式,不建议使用double构造方式。

    public BigDecimal(String val); 
    public BigDecimal(double val);

    Bigdecimal常用方法:

    加减乘除: add()、subtract()、multiply()、divide().

    注意:

    使用BigDecimal类构造方法传入double类型时,计算的结果也是不精确的;
    因为不是所有的浮点数都能够被精确的表示成一个double 类型值,因此它会被表示成与它最接近的 double 类型的值。必须改用传入String的构造方法。

    舍入模式:

    ......

    二、使用

    1. 使用BigDecimal计算

    public class BigDecimalTest {
        public static void main(String[] args) {
            computed();
            lossAccuracy();
        }
    
        /**
         * 使用BigDecimal 计算
         */
        public static void computed() {
            BigDecimal v1 = new BigDecimal(0.2);
            BigDecimal v2 = new BigDecimal(0.3);
            BigDecimal v3 = new BigDecimal(-0.5);
    
            //尽量用字符串的形式初始化
            BigDecimal s1 = new BigDecimal("0.2");
            BigDecimal s2 = new BigDecimal("0.3");
            BigDecimal s3 = new BigDecimal("-0.5");
    
            //加法
            BigDecimal addVal = v1.add(v2);
            System.out.println("加法用value结果:" + addVal);  // 0.50000000...
            BigDecimal addStr = s1.add(s2);
            System.out.println("加法用string结果:" + addStr); // 0.5
    
            //减法
            BigDecimal subtractVal = v2.subtract(v1);
            System.out.println("减法value结果:" + subtractVal); // 0.09999999
            BigDecimal subtractStr = s2.subtract(s1);
            System.out.println("减法用string结果:" + subtractStr); // 0.1
    
            //乘法
            BigDecimal multiplyVal = v1.multiply(v2);
            System.out.println("乘法用value结果:" + multiplyVal); // 0.060000...
            BigDecimal multiplyStr = s1.multiply(s2);
            System.out.println("乘法用string结果:" + multiplyStr); // 0.06
    
            //除法
            BigDecimal divideVal = v2.divide(v1, 4, BigDecimal.ROUND_HALF_UP);
            System.out.println("除法用value结果:" + divideVal); // 1.5000
            BigDecimal divideStr = s2.divide(s1, 4, BigDecimal.ROUND_HALF_UP);
            System.out.println("除法用string结果:" + divideStr); // 1.5000
    
            //绝对值
            BigDecimal absVal = v3.abs();
            System.out.println("绝对值用value结果:" + absVal); // 0.5
            BigDecimal absStr = s3.abs();
            System.out.println("绝对值用string结果:" + absStr); // 0.5
        }
    
        /**
         * 采用浮点型数据运算可能会丢失精度
         */
        public static void lossAccuracy() {
            System.out.println(0.05 + 0.01);//0.060000000000000005
            System.out.println(1.0 - 0.42);//0.5800000000000001
            System.out.println(4.015 * 100);//401.49999999999994
            System.out.println(123.3 / 100);//1.2329999999999999
            System.out.println(Math.round(4.015 * 100) / 100.0);// 4.01 四舍五入保留两位
        }
    }

    使用除法函数在divide的时候要设置各种参数,要有除数、精确的小数位数和舍入模式,不然会出现报错。

    2. 除法计算时需要设置舍入模式 

    常用方法:

    divide(BigDecimal divisor, int scale, RoundingMode roundingMode)

    divide(BigDecimal divisor, int scale, int roundingMode) 

    参数:

    divisor:因子,被除数

    scale: 刻度,保留的位数

    roundingMode:舍入模式

               RoundingMode是一个枚举类,枚举类型的值指向的BigDecimal中的值;

            int类型的值,直接从BigDecimal中的静态变量获取;

            

    参考:

    BigDecimal加减乘除计算

  • 相关阅读:
    使用xfire
    db2 存储过程编写定义
    mac下使用eclipse的svn报错问题

    nsis打包过程
    mac快捷键以及增加桌面
    struts2 无法访问static目录下的内容的解决办法
    linux下安装db2
    ORACLE01034错误解决
    cannot restore segment prot after reloc: Permission denied
  • 原文地址:https://www.cnblogs.com/shiyun32/p/12425551.html
Copyright © 2011-2022 走看看