Detailed explanation of BigDecimal usage

1 Introduction

The API class BigDecimal provided by Java in the java.math package is used to perform precise operations on numbers with more than 16 significant digits. The double-precision floating-point variable double can handle a 16-bit significand. In practical applications, operations and processing of larger or smaller numbers are required. float and double can only be used for scientific calculations or engineering calculations, and java.math.BigDecimal is used in commercial calculations. What BigDecimal creates is an object, and we cannot use traditional +, -, *, / and other arithmetic operators to directly perform mathematical operations on its object, but must call its corresponding method. The parameters in the method must also be BigDecimal objects. Constructors are special methods of classes designed to create objects, especially objects with parameters.

2 Recommended articles

Why does Alibaba prohibit the use of BigDecimal's equals method for equality comparison?

Do you think that after using BigDecimal, the calculation result must be accurate?

3 Constructor

BigDecimal(int)       Creates an object with the integer value specified by the parameter.
BigDecimal(long)      Creates an object with the long value specified by the parameter.
BigDecimal(double)    Creates an object with the double value specified by the parameter. [Prohibited to use]
BigDecimal(String)    Creates an object with the numeric value specified by the parameter as a string.

4 Common API s

add(BigDecimal)        BigDecimal Add the values ​​in the object and return this object
subtract(BigDecimal)   BigDecimal Subtract the values ​​in the object and return this object
multiply(BigDecimal)   BigDecimal Multiply the values ​​in the object and return this object
divide(BigDecimal)     BigDecimal Divide the values ​​in the object and return this object

toString()             Will BigDecimal Convert the numeric value of an object to a string
doubleValue()          Will BigDecimal The value in the object is returned as a double
floatValue()           Will BigDecimal The value in the object is returned as a single precision number
longValue()            Will BigDecimal The value in the object is returned as a long integer
intValue()             Will BigDecimal The value in the object is returned as an integer

5 API Details

5.1 Two decimal places

public class DecimalTest {

    public static void main(String[] s) {

        double num = 13.154215;

        //method one
        DecimalFormat df1 = new DecimalFormat("0.00");
        String str = df1.format(num);
        //output 13.15
        System.out.println(str);

        //Method 2
        // #.00 Indicates two decimal places #.0000 four decimal places
        DecimalFormat df2 = new DecimalFormat("#.00");
        String str2 = df2.format(num);
        //output 13.15
        System.out.println(str2);

        //way three
        //%.2f %. means any number of digits before the decimal point 2 means two decimal places The result after the format is f Represents a floating point type
        String result = String.format("%.2f", num);
        //output 13.15
        System.out.println(result);
    }
}

5.2 Rounding


public class DecimalTest {

    public static void main(String[] s) {

        double testA = new BigDecimal("1.555555").setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        //output 1.56
        System.out.println(testA);
        //because BigDecimal The property is ROUND_HALF_UP,The discarded part is: 0.005555 = 0.5555,Meet the discarded part >=0.5,So it will go up by one, if the discarded part is 0.004555
        //will not go up one

        double testB = new BigDecimal("1.555").setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue();
        //output 1.55
        System.out.println(testB);
        //because BigDecimal The property is ROUND_HALF_DOWN,The discarded part is: 0.005 = 0.5,No>0.5,So it won't go up one

        double testC = new BigDecimal("1.55555").setScale(2, BigDecimal.ROUND_HALF_DOWN).doubleValue();
        //output 1.56
        System.out.println(testC);
        //because BigDecimal The property is ROUND_HALF_DOWN,The discarded part is: 0.00555 = 0.555,Meet the discarded part>0.5,So it will go up one
    }
}


illustrate:
setScale(1) means to keep one decimal place, the default is rounding
setScale(1, BigDecimal.ROUND_DOWN) directly delete the extra decimal places, such as 2.35 will become 2.3
setScale(1, BigDecimal.ROUND_UP) carry processing, 2.35 becomes 2.4
setScale(1, BigDecimal.ROUND_HALF_UP) rounds up, 2.35 becomes 2.4, 2.33 becomes 2.3
setScaler(1, BigDecimal.ROUND_HALF_DOWN) rounds up, 2.35 becomes 2.3, if it is 5, it rounds down
setScaler(1, BigDecimal.ROUND_CEILING) rounds near positive infinity
setScaler(1, BigDecimal.ROUND_FLOOR) rounds close to negative infinity. Numbers > 0 have the same effect as ROUND_UP, and numbers < 0 have the same effect as ROUND_DOWN
setScaler(1, BigDecimal.ROUND_HALF_EVEN) rounds to the nearest number, or to the next even number if it is equidistant from two adjacent numbers.

5.3 Formatting

Since the format() method of the NumberFormat class can use a BigDecimal object as its parameter, you can use BigDecimal to control the formatting of currency values, percent values, and general values ​​that exceed 16 significant digits.

public class DecimalTest {

    public static void main(String[] s) {
        //Create currency formatting references
        NumberFormat currency = NumberFormat.getCurrencyInstance();
        //Create percent-formatted citations
        NumberFormat percent = NumberFormat.getPercentInstance();
        //Percentage with up to 3 decimal places
        percent.setMaximumFractionDigits(3);

        //loan amount
        BigDecimal loanAmount = new BigDecimal("150.48");
        //interest rate
        BigDecimal interestRate = new BigDecimal("0.008");
        //multiply
        BigDecimal interest = loanAmount.multiply(interestRate);

        //loan amount: ¥150.48
        System.out.println("loan amount:\t" + currency.format(loanAmount));
        //interest rate: 0.8%
        System.out.println("interest rate:\t" + percent.format(interestRate));
        //Interest: ¥1.20
        System.out.println("Interest:\t" + currency.format(interest));
    }
}
public class DecimalTest {

    public static void main(String[] s) {
        DecimalFormat df = new DecimalFormat();
        //number before formatting
        double data = 1234.56789;

        //1,Defines the format of the number to be displayed (this way it will be rounded)
        String style = "0.0";
        df.applyPattern(style);
        //1234.6
        System.out.println("1-->" + df.format(data));

        //2,Add characters such as units after the format
        style = "00000.000 kg";
        df.applyPattern(style);
        //01234.568 kg
        System.out.println("2-->" + df.format(data));

        //3, in mode"#" means that if the character exists in the bit, display the character, if not, it does not display.
        style = "##000.000 kg";
        df.applyPattern(style);
        //1234.568 kg
        System.out.println("3-->" + df.format(data));

        //4, in mode"-"Indicates that the output is a negative number and should be placed at the top
        style = "-000.000";
        df.applyPattern(style);
        //-1234.568
        System.out.println("4-->" + df.format(data));

        //5, in mode","Add commas to numbers to make numbers easier to read
        style = "-0,000.0#";
        df.applyPattern(style);
        //5-->-1,234.57
        System.out.println("5-->" + df.format(data));

        //6,in mode"E"represents the output as an exponential,"E"The previous string is in base format,
        // "E"After the string is the format of the exponent
        style = "0.00E000";
        df.applyPattern(style);
        //6-->1.23E003
        System.out.println("6-->" + df.format(data));

        //7, in mode"%"Indicates multiplied by 100 and displayed as a percentage, to be placed at the end.
        style = "0.00%";
        df.applyPattern(style);
        //7-->123456.79%
        System.out.println("7-->" + df.format(data));

        //8, in mode"\u2030"Indicates that it is multiplied by 1000 and displayed as thousandths, which should be placed at the end.
        style = "0.00\u2030";
        //Set the number format in the constructor
        DecimalFormat df1 = new DecimalFormat(style);
        //df.applyPattern(style);
        //8-->1234567.89‰
        System.out.println("8-->" + df1.format(data));
    }
}

5.4 BigDecimal comparison

public class DecimalTest {

    public static void main(String[] s) {

        // Note that you cannot use equals method to compare sizes
        // use BigDecimal The downside is the performance ratio double and float Poor, especially when dealing with huge and complex operations, because which type to use is determined according to actual needs
        BigDecimal a = new BigDecimal("1");
        BigDecimal b = new BigDecimal("2");
        BigDecimal c = new BigDecimal("1");
        int result1 = a.compareTo(b);
        int result2 = a.compareTo(c);
        int result3 = b.compareTo(a);

        //output -1
        System.out.println(result1);
        //output 0
        System.out.println(result2);
        //output 1
        System.out.println(result3);
    }
}

5.5 Scientific Notation

 Some projects may involve importing data from Excel, but if the cell type in Excel is numeric, but the content data is too long (such as bank account number), it will be read as scientific notation by default when importing, and it is easy to use the following code solve.

public class DecimalTest {

    public static void main(String[] s) {

        BigDecimal bd = new BigDecimal("3.40256010353E11");
        String result = bd.toPlainString();
        //output 340256010353
        System.out.println(result);
    }
}

5.6 Dealing with commas in price numbers

public class DecimalTest {

    public static void main(String[] s) {

        java.util.StringTokenizer st = new StringTokenizer( "123,456,789", ",");
        StringBuilder sb = new StringBuilder();
        while(st.hasMoreTokens())   {
            sb.append(st.nextToken());
        }
        //output 123456789
        System.out.println(sb);

        String str = "123,456,789";
        str = str.replace(",", "");
        //output 123456789
        System.out.println(str);
    }
}

5.7 Exact calculation

public class DecimalTest {

    public static void main(String[] s) {

        double value1 = 1.00;
        String value2 = "1.00";
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = new BigDecimal(value2);
        System.out.println(b1);
        System.out.println(b2);
    }
}

5.8 Package tool class

public class BigDecimalUtil {
    /**
     * add method that provides exact addition calculations 
     * @param value1 summand 
     * @param value2 addend 
     * @return the sum of the two parameters
     */
    public static double add(double value1,double value2){
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.add(b2).doubleValue();
    }

    /**
     * sub method that provides exact subtraction operations 
     * @param value1 Minuend 
     * @param value2 Subtraction 
     * @return difference between two parameters
     */
    public static double sub(double value1,double value2){
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * mul method that provides exact multiplication 
     * @param value1 Multiplier 
     * @param value2 multiplier 
     * @return product of two parameters
     */
    public static double mul(double value1,double value2){
        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.multiply(b2).doubleValue();
    }

    /**
     * Provides exact division method div 
     * @param value1 dividend 
     * @param value2 divisor 
     * @param scale Exact range 
     * @return Quotient of two parameters
     * @throws IllegalAccessException
     */
    public static double div(double value1,double value2,int scale) throws IllegalAccessException{
        //If the exact range is less than 0, throw an exception message  
        if(scale<0){
            throw new IllegalAccessException("Accuracy cannot be less than 0");
        }

        BigDecimal b1 = BigDecimal.valueOf(value1);
        BigDecimal b2 = BigDecimal.valueOf(value2);
        return b1.divide(b2, scale).doubleValue();
    }
}  

Original link: https://blog.csdn.net/qidasheng2012/article/details/84936397

Tags: Java

Posted by deansatch on Wed, 14 Sep 2022 22:56:36 +0530