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

posted @   一帘幽梦&nn  阅读(267)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击查看具体代码内容
点击右上角即可分享
微信分享提示