首页 > 其他分享 >BigDecimal 使用总结

BigDecimal 使用总结

时间:2023-01-17 12:33:11浏览次数:54  
标签:总结 BigDecimal System bd1 使用 println 小数 out

工作中很多情况下需要进行精确的小数运算,,在 Java 中使用 float 和 double 这两种浮点数类型进行小数运算时,往往很难达到令人满意的效果,小数点后面总是存在很多位的小数,看起来令人费解,因此不推荐使用这两种浮点数类型进行小数运算。BigDecimal 就是专门用来进行精确计算的,使用起来也非常方便,下面我们就通过代码一起看一下吧。


一、运算效果对比

先给出代码和运算结果,然后再进行结论总结。

package com.jobs;

import java.math.BigDecimal;

public class Demo1 {
    public static void main(String[] args) {

        double f1 = 0.1;
        double f2 = 0.2;
        double result1 = f1 + f2;
        System.out.println("Double相加的结果:" );
        System.out.println(result1);

        System.out.println("-----------------");

        //使用浮点数初始化BigDecimal
        BigDecimal bd1 = new BigDecimal(0.1);
        BigDecimal bd2 = new BigDecimal(0.2);
        BigDecimal result2 = bd1.add(bd2);
        System.out.println("浮点数初始化的BigDecimal相加的结果:");
        System.out.println(result2);

        System.out.println("-----------------");

        BigDecimal bd3 = new BigDecimal("0.1");
        BigDecimal bd4 = new BigDecimal("0.2");
        BigDecimal result3 = bd3.add(bd4);
        System.out.println("字符串初始化的BigDecimal相加的结果:");
        System.out.println(result3);

    }
}

执行的结果是:

image

从上面的执行结果,可以看出:

【double 类型的小数】和【使用浮点数初始化的 BigDecimal 】在进行小数运算后,结果并不是我们所期望的,甚至【使用浮点数初始化的 BigDecimal 小数】进行小数运算的结果,更加令人感到不爽。

【使用字符串初始化的 BigDecimal 】进行小数运算后的结果,是我们所期望的结果,因此后续尽量使用字符串来初始化 BigDecimal 。


二、BigDecimal 运算示例

还是先给出代码,再总结结论吧:

package com.jobs;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Demo2 {
    public static void main(String[] args) {

        BigDecimal bd1 = new BigDecimal("10");
        BigDecimal bd2 = new BigDecimal("3");

        //相加
        BigDecimal add = bd1.add(bd2);
        System.out.println("10/3 相加的结果:" + add);

        //相减
        BigDecimal subtract = bd1.subtract(bd2);
        System.out.println("10/3 相减的结果:" + subtract);

        //相乘
        BigDecimal multiply = bd1.multiply(bd2);
        System.out.println("10/3 相乘的结果:" + multiply);

        //相除(如果能够除尽,则一切正常)
        BigDecimal divide = bd2.divide(bd1);
        System.out.println("3/10 相除的结果:" + divide);

        //相除(如果除不尽,则抛异常)
        //原因:BigDecimal属于精确计算,如果除不尽,必须指定舍入规则
        BigDecimal divide0 = bd1.divide(bd2);
        System.out.println("10/3 相除的结果:" + divide0);
    }
}

执行的结果是:

image

从执行的结果,可以看出:

【使用字符串初始化的 BigDecimal 】在进行除法运算时,如果能够除尽的话,代码运行就正常,如果除不尽的话,就会抛出异常。原因就是 BigDecimal 属于精确运算,如果除不尽的话,必须要指定小数的舍入规则,这样才能确保运算的结果是我们预期的结果。


三、常用的小数舍入规则

系统提供了很多小数舍入规则,我们常用的也就是 3 种舍入规则:

  • RoundingMode.UP 进一法
  • RoundingMode.FLOOR 去尾法
  • RoundingMode.HALF_UP 四舍五入
package com.jobs;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Demo2 {
    public static void main(String[] args) {

        BigDecimal bd1 = new BigDecimal("10");
        BigDecimal bd2 = new BigDecimal("3");

        //常用的三个舍入规则为:
        //RoundingMode.UP 进一法
        //RoundingMode.FLOOR 去尾法
        //RoundingMode.HALF_UP 四舍五入

        System.out.println("相除精确2位小数:");

        BigDecimal divide1 = bd1.divide(bd2, 2, RoundingMode.UP);
        System.out.println("10/3 小数第3位进1的结果:" + divide1);

        BigDecimal divide2 = bd1.divide(bd2, 2, RoundingMode.FLOOR);
        System.out.println("10/3 小数第3位舍去的结果:" + divide2);

        BigDecimal divide3 = bd1.divide(bd2, 2, RoundingMode.HALF_UP);
        System.out.println("10/3 小数第3位四舍五入的结果:" + divide3);

        BigDecimal bd3 = new BigDecimal("0.1");
        BigDecimal bd4 = new BigDecimal("4");
        BigDecimal divide4 = bd3.divide(bd4, 2, RoundingMode.HALF_UP);
        System.out.println("0.1/4 实际结果是 0.025,小数第3位四舍五入的结果:" + divide4);
    }
}

执行结果如下:

image

以上就是三种舍入规则的效果演示,平时使用最多的应该还是四舍五入。我们在使用 BigDecimal 进行除法运算时,尽量指定要保留的小数位数,以及舍入规则,否则就会有除不尽导致代码执行过程中抛异常的风险。


Ok,到此为止,有关 BigDecimal 的基本使用,已经介绍的差不多了,相关的示例代码下载地址如下:

https://files.cnblogs.com/files/blogs/699532/BigDecimalDemo.zip


标签:总结,BigDecimal,System,bd1,使用,println,小数,out
From: https://www.cnblogs.com/studyjobs/p/17057546.html

相关文章

  • 在WPF程序中,使用Freetype显示字体
    本人使用WPF开发了一款OFD阅读器,显示字体是阅读器中最重要的功能。处理字体显示有多种方案,几易其稿,最终选用Freetype方案。本文对WPF中如何使用了Freetype做简单描述。OFD......
  • 使用管控平台管理redis集群
    1添加redis集群在数据库资源中添加redis集群,配置参数并将URL中cluster调整为true。2验证配置资源是否正常3操作redis数据库中的数据可以通过使用图形化界面或者命......
  • NestJS 后台管理系统搭建、TypeOrm使用(一)
    前言技术千千万,学习永不断;虽然是咸鱼,也想努把力!!!这段时间一直很迷茫,做前端这行也有6年了,眼看马上奔三的人了,但依旧是个菜逼,整天代码写了不少,但总感觉缺少些什么,一直都没......
  • pytorch使用cat()和stack()拼接tensors
    有时我们在处理数据时,需要对指定的tensor按照指定​​维度​​​进行拼接,对于这个需求,pytorch中提供了两个函数供我们使用,一个是​​torch.cat()​​​,另外一个是​​torch.......
  • pytorch中nn.Parameter()使用方法
    对于​​nn.Parameter()​​​是pytorch中定义​​可学习参数​​的一种方法,因为我们在搭建网络时,网络中会存在一些矩阵,这些矩阵内部的参数是可学习的,也就是可梯度求导的。......
  • BBS项目复习总结
    BBS之用户注册思路梳理:1.新建一个django项目,名称可以和bbs相关,准备好数据库、静态模板资源及配置好模板、数据库、用户表重命名配置。2.先准备bbs项目8张表,并理清表之前......
  • 使用Rancher管理K3s
    rancher中国镜像站地址https://rancher-mirror.oss-cn-beijing.aliyuncs.com/https://rancher-mirror.rancher.cn/k3s  rancher路径和中文镜像的对应关系k3s安装......
  • Vue 使用localStorage报错:_LocalStorage2.default.getItem is not a function
    问题在mounted中使用localStorage获取数据,没想到报错如下:打断点看过localStorage中存在getItem()方法。这个问题类似之前遇到的canvas2image的那个问题(canvasToImage报......
  • 如何使用Java异步编程(多线程CompletableFuture)
    1、创建异步线程任务根据supplier创建CompletableFuture任务//使用内置线程ForkJoinPool.commonPool(),根据supplier构建执行任务publicstatic<U>CompletableFuture......
  • MySQL必知必会第十一章-使用数据处理函数
    使用数据处理函数函数与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数一般是在数据上执行的,它给数据的转换和处理提供了方便。注意:函数没有SQL的可移植性......