浮点数据精确计算之~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加减乘除计算

原文地址:https://www.cnblogs.com/shiyun32/p/12425551.html