首页 > 编程语言 >Java之API详解之BigDecimal类的详细解析

Java之API详解之BigDecimal类的详细解析

时间:2023-12-02 23:31:56浏览次数:54  
标签:Java 运算 divide API b1 b2 public BigDecimal


 7 BigDecimal类

7.1 引入

首先我们来分析一下如下程序的执行结果:

public class BigDecimalDemo01 {

    public static void main(String[] args) {
        System.out.println(0.09 + 0.01);
    }

}

Java之API详解之BigDecimal类的详细解析_System

这段代码比较简单,就是计算0.09和0.01之和,并且将其结果在控制台进行输出。那么按照我们的想法在控制台输出的结果应该为0.1。那么实际的运行结果是什么呢?我们来运行一下程序,控制台的输出

结果如下所示:

0.09999999999999999

Java之API详解之BigDecimal类的详细解析_数据_02

这样的结果其实就是一个丢失精度的结果。为什么会产生精度丢失呢?

在使用float或者double类型的数据在进行数学运算的时候,很有可能会产生精度丢失问题。我们都知道计算机底层在进行运算的时候,使用的都是二进制数据; 当我们在程序中写了一个十进制数据 ,在

进行运算的时候,计算机会将这个十进制数据转换成二进制数据,然后再进行运算,计算完毕以后计算机会把运算的结果再转换成十进制数据给我们展示; 如果我们使用的是整数类型的数据进行计算,那

么在把十进制数据转换成二进制数据的时候不会存在精度问题; 如果我们的数据是一个浮点类型的数据,有的时候计算机并不会将这个数据完全转换成一个二进制数据,而是将这个将其转换成一个无限的

趋近于这个十进数的二进制数据; 这样使用一个不太准确的数据进行运算的时候, 最终就会造成精度丢失;为了提高精度,Java就给我们提供了BigDecimal供我们进行数据运算。

7.2 概述

查看API文档,我们可以看到API文档中关于BigDecimal类的定义如下:

Java之API详解之BigDecimal类的详细解析_数据_03

Java之API详解之BigDecimal类的详细解析_System_04编辑

BigDecimal所在包是在java.math包下,因此在使用的时候就需要进行导包。我们可以使用BigDecimal类进行更加精准的数据计算。

7.3 常见方法

构造方法

要用BigDecimal类,那么就需要首先学习一下如何去创建BigDecimal的对象。通过查看API文档,我们可以发现Jdk中针对BigDecimal类提供了很多的构造方法,但是最常用的构造方法是:

Java之API详解之BigDecimal类的详细解析_System_05

Java之API详解之BigDecimal类的详细解析_数据_06编辑

了解完常见的构造方法以后,我们接下来就重点介绍一下常见的成员方法。

常见成员方法

BigDecimal类中使用最多的还是提供的进行四则运算的方法,如下:

public BigDecimal add(BigDecimal value)				// 加法运算
public BigDecimal subtract(BigDecimal value)		// 减法运算
public BigDecimal multiply(BigDecimal value)		// 乘法运算
public BigDecimal divide(BigDecimal value)			// 触发运算

Java之API详解之BigDecimal类的详细解析_数据_07

接下来我们就来通过一些案例演示一下这些成员方法的使用。

案例1:演示基本的四则运算

代码如下所示:

public class BigDecimalDemo01 {

    public static void main(String[] args) {

        // 创建两个BigDecimal对象
        BigDecimal b1 = new BigDecimal("0.3") ;
        BigDecimal b2 = new BigDecimal("4") ;

        // 调用方法进行b1和b2的四则运算,并将其运算结果在控制台进行输出
        System.out.println(b1.add(b2));         // 进行加法运算
        System.out.println(b1.subtract(b2));    // 进行减法运算
        System.out.println(b1.multiply(b2));    // 进行乘法运算
        System.out.println(b1.divide(b2));      // 进行除法运算

    }

}

Java之API详解之BigDecimal类的详细解析_数据_08

运行程序进行测试,控制台输出结果如下:

4.3
-3.7
1.2
0.075

Java之API详解之BigDecimal类的详细解析_System_09

此时我们可以看到使用BigDecimal类来完成浮点数的计算不会存在损失精度的问题。

案例2:演示除法的特殊情况

如果使用BigDecimal类型的数据进行除法运算的时候,得到的结果是一个无限循环小数,那么就会报错:ArithmeticException。 如下代码所示:

public class BigDecimalDemo02 {

    public static void main(String[] args) {

        // 创建两个BigDecimal对象
        BigDecimal b1 = new BigDecimal("1") ;
        BigDecimal b2 = new BigDecimal("3") ;

        // 调用方法进行b1和b2的除法运算,并且将计算结果在控制台进行输出
        System.out.println(b1.divide(b2));

    }

}

Java之API详解之BigDecimal类的详细解析_数据_10

运行程序进行测试,控制台输出结果如下所示:

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
	at java.base/java.math.BigDecimal.divide(BigDecimal.java:1716)
	at com.itheima.api.bigdecimal.demo02.BigDecimalDemo02.main(BigDecimalDemo02.java:14)

Java之API详解之BigDecimal类的详细解析_System_11

针对这个问题怎么解决,此时我们就需要使用到BigDecimal类中另外一个divide方法,如下所示:

BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)

Java之API详解之BigDecimal类的详细解析_System_12

上述divide方法参数说明:

divisor:			除数对应的BigDecimal对象;
scale:				精确的位数;
roundingMode:		取舍模式;
取舍模式被封装到了RoundingMode这个枚举类中(关于枚举我们后期再做重点讲解),在这个枚举类中定义了很多种取舍方式。最常见的取舍方式有如下几个:
UP(直接进1) , FLOOR(直接删除) , HALF_UP(4舍五入),我们可以通过如下格式直接访问这些取舍模式:枚举类名.变量名

Java之API详解之BigDecimal类的详细解析_System_13

接下来我们就来演示一下这些取舍模式,代码如下所示:

public class BigDecimalDemo02 {

    public static void main(String[] args) {

        // 调用方法
        method_03() ;

    }

    // 演示取舍模式HALF_UP
    public static void method_03() {

        // 创建两个BigDecimal对象
        BigDecimal b1 = new BigDecimal("0.3") ;
        BigDecimal b2 = new BigDecimal("4") ;

        // 调用方法进行b1和b2的除法运算,并且将计算结果在控制台进行输出
        System.out.println(b1.divide(b2 , 2 , RoundingMode.HALF_UP));

    }

    // 演示取舍模式FLOOR
    public static void method_02() {

        // 创建两个BigDecimal对象
        BigDecimal b1 = new BigDecimal("1") ;
        BigDecimal b2 = new BigDecimal("3") ;

        // 调用方法进行b1和b2的除法运算,并且将计算结果在控制台进行输出
        System.out.println(b1.divide(b2 , 2 , RoundingMode.FLOOR));

    }

    // 演示取舍模式UP
    public static void method_01() {

        // 创建两个BigDecimal对象
        BigDecimal b1 = new BigDecimal("1") ;
        BigDecimal b2 = new BigDecimal("3") ;

        // 调用方法进行b1和b2的除法运算,并且将计算结果在控制台进行输出
        System.out.println(b1.divide(b2 , 2 , RoundingMode.UP));

    }

}

Java之API详解之BigDecimal类的详细解析_System_14

小结:后期在进行两个数的除法运算的时候,我们常常使用的是可以设置取舍模式的divide方法。

7.4 底层存储方式:

把数据看成字符串,遍历得到里面的每一个字符,把这些字符在ASCII码表上的值,都存储到数组中。

Java之API详解之BigDecimal类的详细解析_ide_15

Java之API详解之BigDecimal类的详细解析_System_16编辑



标签:Java,运算,divide,API,b1,b2,public,BigDecimal
From: https://blog.51cto.com/u_16265376/8659816

相关文章

  • Java连接MySQL数据库(maven构建)
    构建方式:Java+MySql+Maven1.创建项目2.导入依赖选择目录中的pom.xml文件,导入mysql连接驱动依赖注意这里版本使用的是MySql8.0,MySql在8.0版本有较大改动<dependencies><dependency><groupId>mysql</groupId><ar......
  • 【JavaSE】异常(异常体系、异常处理方式、自定义异常)
    异常介绍异常体系一定要能阐述异常的体系结构!异常类的祖先类:Throwable所有的异常都是一个类,如果不清楚可以在API帮助文档查询运行时异常:编译时没有错误,运行时可能会出错,通常是代码不严谨导致的编译时异常(不包含语法错误):主要起提醒作用,需要在运行之前给出解决方式异常处理......
  • RabbitMQ Java代码声明队列和交换机(方法一)
      交换机和队列的声明一般写在消费者模块里 代码示例:packagecom.itheima.config_RabbitMQ;importorg.springframework.amqp.core.*;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@Configuration......
  • sap.fe.templates.ListReport.ExtensionAPI 的使用场合介绍
    SAPFioriElements是一种用于快速开发SAPFiori应用程序的框架,它通过提供预定义的UI元素和模板,简化了开发过程。其中,sap.fe.templates.ListReport.ExtensionAPI是SAPFioriElements框架中的一个重要组件,用于扩展ListReport应用程序的功能。SAPFioriElements概述在深入探讨s......
  • sap.suite.ui.generic.template.ListReport.extensionAPI.ExtensionAPI 的使用场合介
    首先让我们了解一下什么是sap.suite.ui.generic.template.ListReport.extensionAPI.ExtensionAPI。这是一个在SAPFioriElements中用于扩展ListReport应用的API。SAPFioriElements旨在提供一种简洁,高效且一致的用户体验,而不需要开发人员编写大量的前端代码。然而,有些情......
  • SAP Fiori Elements 针对 OData V2 和 V4 的 Extension API
    sap.suite.ui.generic.template.ListReport.extensionAPI.ExtensionAPI属于SAPFioriElements的早期版本,它基于SAPUI5框架构建,主要是针对ABAP环境下的ODataV2服务。sap.fe.templates.ListReport.ExtensionAPI是新的FiorielementsforODatav4的一部分,它是基于SA......
  • 算法之快速排序1初始(java)
    一:概述快速排序、归并排序、堆排序等都是比冒泡排序更快的算法。其中快速排序是从冒泡排序演变而来。快速排序之所以比冒泡排序要快是因为它用了分治法。    二:具体说明同冒泡排序一样,快速排序也属于交换排序,通过元素之间的比较进行比较和交换位置来达到排序的目的。不同的是......
  • 【算法 Java】递归,阶乘的递归实现,斐波那契数列的递归实现
    递归定义:方法直接或间接地调用方法本身思路:将大问题转化为一个与原问题相似的规模更小的问题注意:递归死循环会导致栈内存溢出一些使用递归求解的问题阶乘Factorial.javaimportjava.util.Scanner;publicclassFactorial{publicstaticvoidmain(String[]args)......
  • ElasticSearch之Refresh API
    使用本方法,显式的执行refresh操作。默认情况下,ElasticSearch启动后台任务,周期性执行refresh操作,周期使用参数index.refresh_interval控制。本方法触发的refresh为同步操作,运行完毕之后才会返回任务的执行结果。指定索引,执行refresh操作。命令样例如下:curl-XPOST"https://l......
  • ElasticSearch之Index stats API
    获取指定索引的统计数据。获取指定索引的全部统计数据,命令样例如下:curl-XGET"https://localhost:9200/testindex_001/_stats?pretty"--cacert$ES_HOME/config/certs/http_ca.crt-u"elastic:ohCxPH=QBE+s5=*lo7F9"执行结果的样例,如下:{"_shards":{"total&q......