Detailed analysis of the BigDecimal class of Java's API detailed explanation

7 BigDecimal class

7.1 Introduction

First, let's analyze the execution results of the following program:

public class BigDecimalDemo01 {

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

}

This code is relatively simple, it is to calculate the sum of 0.09 and 0.01, and output the result on the console. Then according to our idea, the result output on the console should be 0.1. So what is the actual running result? Let's run the program, the console output

The result looks like this:

0.09999999999999999

This result is actually a result of loss of precision. Why is there a loss of precision?

When using float or double type data to perform mathematical operations, it is very likely that precision loss will occur. We all know that when the bottom layer of the computer is performing calculations, it uses binary data; when we write a decimal data in the program, in

When performing calculations, the computer will convert the decimal data into binary data, and then perform calculations. After the calculation is completed, the computer will convert the calculation results into decimal data and show us; if we use integer type data for calculation ,That

So there will be no precision problems when converting decimal data into binary data; if our data is a floating-point type of data, sometimes the computer will not completely convert this data into a binary data, but this convert it into an infinite

Binary data close to this decimal number; in this way, when using an inaccurate data for calculation, the precision will eventually be lost; in order to improve the precision, Java provides us with BigDecimal for us to perform data calculations.

7.2 Overview

Looking at the API documentation, we can see that the definition of the BigDecimal class in the API documentation is as follows:

The package where BigDecimal is located is under the java.math package, so it needs to be imported when using it. We can use the BigDecimal class for more precise data calculations.

7.3 Common methods

Construction method

To use the BigDecimal class, you need to first learn how to create BigDecimal objects. By looking at the API documentation, we can find that Jdk provides many construction methods for the BigDecimal class, but the most commonly used construction methods are:

After understanding the common construction methods, let's focus on the common member methods.

common member methods

The most used method in the BigDecimal class is the method of performing four arithmetic operations, as follows:

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

Next, let's demonstrate the use of these member methods through some cases.

Case 1 : Demonstrate the basic four operations

The code looks like this:

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));      // 进行除法运算

    }

}

Run the program to test, the console output is as follows:

4.3
-3.7
1.2
0.075

At this point we can see that using the BigDecimal class to complete the calculation of floating-point numbers will not cause loss of precision.

Case 2 : Demonstrating a special case of division

If the result of division operation using BigDecimal type data is an infinite repeating decimal, an error will be reported: ArithmeticException. As shown in the following code:

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));

    }

}

Run the program to test, the console output is as follows:

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)

To solve this problem, we need to use another divide method in the BigDecimal class, as shown below:

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

The above divide method parameter description:

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

Next, let's demonstrate these trade-off modes. The code is as follows:

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));

    }

}

Summary: When performing the division operation of two numbers later, we often use the divide method that can set the rounding mode.

7.4 Underlying storage method:

Treat the data as a string, traverse to get each character in it, and store the values ​​of these characters in the ASCII code table into the array.

Guess you like

Origin blog.csdn.net/qq_69748833/article/details/132612563