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加减乘除计算

  • 相关阅读:
    python异常处理--try except else raise finally
    WEB自动化+Allure+Jenkins定时构建
    pytest框架优化——将异常截屏图片加入到allure报告中
    pytest框架优化——清理历史截图图片和allure报告文件
    allure 定制化输出测试报告,用例模块名称、用例名称、测试用例的严重级别、测试用例的步骤、用于向测试报告中输入一些附加的信息,通常是一些测试数据信息、链接、用例描述
    Jenkins—Master/Slave 模式
    Jenkins新建节点,启动方式没有“通过Java Web启动代理”选项怎么办?
    pytest 框架之 allure 报告
    pytest 之重运行机制:rerunfailures
    pytest 之 fixture 的前置后置功能
  • 原文地址:https://www.cnblogs.com/shiyun32/p/12425551.html
Copyright © 2011-2022 走看看