BigDecimal common details

Click above“ Programmer Xiaole "Attention,   Star standard or top grow together

At 00:00 a.m. every day,   Meet you for the first time

Daily English

Forgetting someone doesn't mean never think of him, but thinking of him with a calm heart.

Forget a person, not no longer think of, but occasionally think of, but there are no waves in my heart.

Daily heart to heart talk

Don't say that the heart of seeing through the world of mortals is cold, the world of mortals is pure and turbid, wandering and surging; Don't say that talent is a paving block for marriage.

From: LanceToBigData  | Editor: lele

Link: cnblogs.com/zhangyinhua/p/11545305.html

927th tweet by programmer ID: study_tech   Source: Baidu

Past review: It's enough to read this article at the beginning of Docker. Explain it in ten thousand words!

     

    text    

1, BigDecimal overview

The API class BigDecimal provided by Java in the java.math package is used to accurately calculate the number of significant bits exceeding 16 bits. Double, a double precision floating-point variable, can handle 16 bit significant numbers, but in practical applications, it may be necessary to operate and process larger or smaller numbers.

In general, for those numbers that do not need accurate calculation accuracy, we can directly use Float and Double, but Double.valueOf(String) and Float.valueOf(String) will lose accuracy. Therefore, in development, if we need accurate calculation results, we must use BigDecimal class to operate.

BigDecimal creates objects, so we can't use traditional arithmetic operators such as +, -, *, / to directly perform mathematical operations on its objects, but must call its corresponding methods. The parameter in the method must also be an object of BigDecimal. Constructors are special methods of classes that are specifically used to create objects, especially objects with parameters.

2, BigDecimal common constructor


2.1. Common constructors

  • BigDecimal(int)

Creates an object with the integer value specified by the parameter

  • BigDecimal(double)

Creates an object with the double value specified by the parameter

  • BigDecimal(long)

Creates an object with the long integer value specified by the parameter

  • BigDecimal(String)

Creates an object with the value specified by the parameter as a string

2.2 analysis of use problems

Use example:

 
  1. BigDecimal a = new BigDecimal( 0.1);
  2. System.out. println( "a values is:"+a);
  3. System.out. println( "=====================");
  4. BigDecimal b = new BigDecimal( "0.1");
  5. System.out. println( "b values is:"+b);

Examples of results:

 
  1. a values is: 0.1000000000000000055511151231257827021181583404541015625
  2. =====================
  3. b values is: 0.1

Cause analysis:

1) The result of the construction method with parameter type double is unpredictable. One might think that the BigDecimal created by writing newBigDecimal(0.1) in Java is exactly equal to 0.1 (non scale value 1, its scale is 1), but it is actually equal to 0.100000000000055512312578217021181583404541015625. This is because 0.1 cannot be accurately expressed as double (or, in this case, as any binary decimal of finite length). In this way, the value passed into the constructor will not be exactly equal to 0.1 (although it is ostensibly equal to that value).

2) The String construction method is completely predictable: writing newBigDecimal("0.1") will create a BigDecimal, which is exactly equal to the expected 0.1. Therefore, in comparison, it is generally recommended to give priority to the String construction method.

3) When double must be used as the source of BigDecimal, please note that this construction method provides an accurate conversion; It does not provide the same results as the following operations: first use the Double.toString(double) method, and then use the BigDecimal(String) construction method to convert double to String. To get the result, use the static valueOf(double) method.

3, Detailed explanation of common methods of BigDecimal

3.1 common methods

  • add(BigDecimal)

The BigDecimal object is returned by adding the values in the BigDecimal object

  • subtract(BigDecimal)

The BigDecimal object is returned by subtracting the values in the BigDecimal object

  • multiply(BigDecimal)

Returns a BigDecimal object by multiplying the values in the BigDecimal object

  • divide(BigDecimal)

Returns the BigDecimal object by dividing the values in the BigDecimal object

  • toString()

Converts the value in the BigDecimal object to a string

  • doubleValue()

Converts the value in the BigDecimal object to a double

  • floatValue()

Converts the value in the BigDecimal object to a single precision number

  • longValue()

Converts the value in the BigDecimal object to a long integer

  • intValue()

Converts the value in the BigDecimal object to an integer

3.2 BigDecimal size comparison

In java, BigDecimal's compareTo method is generally used to compare the size of BigDecimal

int a = bigdemical.compareTo(bigdemical2)

 

Return result analysis:

 
  1. a =  -1,express bigdemical less than bigdemical2;
  2. a =  0,express bigdemical be equal to bigdemical2;
  3. a =  1,express bigdemical greater than bigdemical2;

Example: a is greater than or equal to b

new bigdemica(a).compareTo(new bigdemical(b)) >= 0

 


4, BigDecimal formatting

Because the format() method of NumberFormat class can use BigDecimal object as its parameter, BigDecimal can be used to format and control the currency value, percentage value and general value exceeding 16 significant digits.

Take the format of currency and percentage with BigDecimal as an example. First, create a BigDecimal object. After the arithmetic operation of BigDecimal, establish references to currency and percentage formatting respectively. Finally, use the BigDecimal object as a parameter of the format() method to output its formatted currency value and percentage.

 
  1. NumberFormat currency = NumberFormat.getCurrencyInstance();  //Create currency formatting reference  
  2. NumberFormat percent = NumberFormat.getPercentInstance();   //Create percentage formatting reference  
  3. percent.setMaximumFractionDigits( 3);  //The percentage has a maximum of 3 decimal places  
  4. BigDecimal loanAmount =  new BigDecimal( "15000.48");  //Loan amount
  5. BigDecimal interestRate =  new BigDecimal( "0.008");  //interest rate    
  6. BigDecimal interest = loanAmount.multiply(interestRate);  //Multiply
  7. System.out. println( "Loan amount:\t" + currency.format(loanAmount)); 
  8. System.out. println( "interest rate:\t" + percent.format(interestRate)); 
  9. System.out. println( "interest:\t" + currency.format(interest)); 

result:

Loan amount: ¥15,000.48 interest rate: 0.8% interest: ¥120.00

 

BigDecimal format, keep 2 as decimal, and supplement 0 if it is insufficient:

 
  1. public class NumberFormat {
  2.     public static void main(String[] s){
  3.         System.out. println(formatToNumber( new BigDecimal( "3.435")));
  4.         System.out. println(formatToNumber( new BigDecimal( 0)));
  5.         System.out. println(formatToNumber( new BigDecimal( "0.00")));
  6.         System.out. println(formatToNumber( new BigDecimal( "0.001")));
  7.         System.out. println(formatToNumber( new BigDecimal( "0.006")));
  8.         System.out. println(formatToNumber( new BigDecimal( "0.206")));
  9.     }
  10.      /**
  11.      * @desc 1.0~1 BigDecimal decimal between. If the previous 0 is lost after formatting, the previous 0 is directly added.
  12.      * 2.If the passed in parameter is equal to 0, the string "0.00" is returned directly
  13.      * 3.For decimals greater than 1, format the returned string directly
  14.      * @param obj Decimal passed in
  15.      * @return
  16.      */
  17.     public static String formatToNumber(BigDecimal obj) {
  18.         DecimalFormat df =  new DecimalFormat( "#.00");
  19.          if(obj.compareTo(BigDecimal.ZERO)== 0) {
  20.              return  "0.00";
  21.         } else  if(obj.compareTo(BigDecimal.ZERO)> 0&&obj.compareTo( new BigDecimal( 1))< 0){
  22.              return  "0"+df.format(obj).toString();
  23.         } else {
  24.              return df.format(obj).toString();
  25.         }
  26.     }
  27. }

The result is:

 
  1. 3.44
  2. 0.00
  3. 0.00
  4. 0.00
  5. 0.01
  6. 0.21


5, BigDecimal common exception


5.1 exception during division

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result

Cause analysis:

When dividing through the divide method of BigDecimal, if there is no integral division and an infinite circular decimal, an exception will be thrown: java.lang.arithmetexception: non terminating decimal expansion; no exact representable decimal result.

resolvent:

The divide method sets the exact decimal point, such as divide(xxxxx,2)

6, BigDecimal summary

6.1 summary

BigDecimal is used when accurate decimal calculation is required. The performance of BigDecimal is worse than double and float, especially when dealing with large and complex operations. Therefore, BigDecimal is not necessary for general accuracy calculation.
Try to use a constructor with a parameter type of String.

BigDecimal is immutable. A new object will be generated every time four operations are performed, so remember to save the value after the operation when performing addition, subtraction, multiplication and division.

6.2. Recommended tools

 
  1. package com.vivo.ars.util;
  2. import java.math.BigDecimal;
  3. /**
  4.  * It is used for high-precision processing of common mathematical operations
  5.  */
  6. public class ArithmeticUtils {
  7.      //Default division precision
  8.     private static final  int DEF_DIV_SCALE =  10;
  9.      /**
  10.      * Provides accurate addition operations
  11.      *
  12.      * @param v1 augend
  13.      * @param v2 Addend
  14.      * @return Sum of two parameters
  15.      */
  16.     public static double add(double v1, double v2) {
  17.         BigDecimal b1 =  new BigDecimal(Double.toString(v1));
  18.         BigDecimal b2 =  new BigDecimal(Double.toString(v2));
  19.          return b1.add(b2).doubleValue();
  20.     }
  21.      /**
  22.      * Provides accurate addition operations
  23.      *
  24.      * @param v1 augend
  25.      * @param v2 Addend
  26.      * @return Sum of two parameters
  27.      */
  28.     public static BigDecimal add(String v1, String v2) {
  29.         BigDecimal b1 =  new BigDecimal(v1);
  30.         BigDecimal b2 =  new BigDecimal(v2);
  31.          return b1.add(b2);
  32.     }
  33.      /**
  34.      * Provides accurate addition operations
  35.      *
  36.      * @param v1    augend
  37.      * @param v2    Addend
  38.      * @param scale Keep scale   Decimal place
  39.      * @return Sum of two parameters
  40.      */
  41.     public static String add(String v1, String v2,  int scale) {
  42.          if (scale <  0) {
  43.             throw  new IllegalArgumentException(
  44.                      "The scale must be a positive integer or zero");
  45.         }
  46.         BigDecimal b1 =  new BigDecimal(v1);
  47.         BigDecimal b2 =  new BigDecimal(v2);
  48.          return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
  49.     }
  50.      /**
  51.      * Provides accurate subtraction
  52.      *
  53.      * @param v1 minuend
  54.      * @param v2 Subtraction
  55.      * @return Difference between two parameters
  56.      */
  57.     public static double sub(double v1, double v2) {
  58.         BigDecimal b1 =  new BigDecimal(Double.toString(v1));
  59.         BigDecimal b2 =  new BigDecimal(Double.toString(v2));
  60.          return b1.subtract(b2).doubleValue();
  61.     }
  62.      /**
  63.      * Provides accurate subtraction.
  64.      *
  65.      * @param v1 minuend
  66.      * @param v2 Subtraction
  67.      * @return Difference between two parameters
  68.      */
  69.     public static BigDecimal sub(String v1, String v2) {
  70.         BigDecimal b1 =  new BigDecimal(v1);
  71.         BigDecimal b2 =  new BigDecimal(v2);
  72.          return b1.subtract(b2);
  73.     }
  74.      /**
  75.      * Provides accurate subtraction
  76.      *
  77.      * @param v1    minuend
  78.      * @param v2    Subtraction
  79.      * @param scale Keep scale   Decimal place
  80.      * @return Difference between two parameters
  81.      */
  82.     public static String sub(String v1, String v2,  int scale) {
  83.          if (scale <  0) {
  84.             throw  new IllegalArgumentException(
  85.                      "The scale must be a positive integer or zero");
  86.         }
  87.         BigDecimal b1 =  new BigDecimal(v1);
  88.         BigDecimal b2 =  new BigDecimal(v2);
  89.          return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
  90.     }
  91.      /**
  92.      * Provide accurate multiplication
  93.      *
  94.      * @param v1 Multiplicand
  95.      * @param v2 multiplier
  96.      * @return Product of two parameters
  97.      */
  98.     public static double mul(double v1, double v2) {
  99.         BigDecimal b1 =  new BigDecimal(Double.toString(v1));
  100.         BigDecimal b2 =  new BigDecimal(Double.toString(v2));
  101.          return b1.multiply(b2).doubleValue();
  102.     }
  103.      /**
  104.      * Provide accurate multiplication
  105.      *
  106.      * @param v1 Multiplicand
  107.      * @param v2 multiplier
  108.      * @return Product of two parameters
  109.      */
  110.     public static BigDecimal mul(String v1, String v2) {
  111.         BigDecimal b1 =  new BigDecimal(v1);
  112.         BigDecimal b2 =  new BigDecimal(v2);
  113.          return b1.multiply(b2);
  114.     }
  115.      /**
  116.      * Provide accurate multiplication
  117.      *
  118.      * @param v1    Multiplicand
  119.      * @param v2    multiplier
  120.      * @param scale Keep scale   Decimal place
  121.      * @return Product of two parameters
  122.      */
  123.     public static double mul(double v1, double v2,  int scale) {
  124.         BigDecimal b1 =  new BigDecimal(Double.toString(v1));
  125.         BigDecimal b2 =  new BigDecimal(Double.toString(v2));
  126.          return round(b1.multiply(b2).doubleValue(), scale);
  127.     }
  128.      /**
  129.      * Provide accurate multiplication
  130.      *
  131.      * @param v1    Multiplicand
  132.      * @param v2    multiplier
  133.      * @param scale Keep scale   Decimal place
  134.      * @return Product of two parameters
  135.      */
  136.     public static String mul(String v1, String v2,  int scale) {
  137.          if (scale <  0) {
  138.             throw  new IllegalArgumentException(
  139.                      "The scale must be a positive integer or zero");
  140.         }
  141.         BigDecimal b1 =  new BigDecimal(v1);
  142.         BigDecimal b2 =  new BigDecimal(v2);
  143.          return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
  144.     }
  145.      /**
  146.      * Provide (relatively) accurate division operation, which is accurate to when there is inexhaustible division
  147.      * 10 digits after the decimal point, and the subsequent figures are rounded
  148.      *
  149.      * @param v1 Divisor
  150.      * @param v2 Divisor
  151.      * @return Quotient of two parameters
  152.      */
  153.     public static double div(double v1, double v2) {
  154.          return div(v1, v2, DEF_DIV_SCALE);
  155.     }
  156.      /**
  157.      * Provides (relatively) accurate division. In case of inexhaustible division, it is specified by the scale parameter
  158.      * To determine the accuracy, the subsequent figures are rounded
  159.      *
  160.      * @param v1    Divisor
  161.      * @param v2    Divisor
  162.      * @param scale Indicates that it needs to be accurate to several decimal places.
  163.      * @return Quotient of two parameters
  164.      */
  165.     public static double div(double v1, double v2,  int scale) {
  166.          if (scale <  0) {
  167.             throw  new IllegalArgumentException( "The scale must be a positive integer or zero");
  168.         }
  169.         BigDecimal b1 =  new BigDecimal(Double.toString(v1));
  170.         BigDecimal b2 =  new BigDecimal(Double.toString(v2));
  171.          return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
  172.     }
  173.      /**
  174.      * Provides (relatively) accurate division. In case of inexhaustible division, it is specified by the scale parameter
  175.      * To determine the accuracy, the subsequent figures are rounded
  176.      *
  177.      * @param v1    Divisor
  178.      * @param v2    Divisor
  179.      * @param scale Indicates that it needs to be accurate to several decimal places
  180.      * @return Quotient of two parameters
  181.      */
  182.     public static String div(String v1, String v2,  int scale) {
  183.          if (scale <  0) {
  184.             throw  new IllegalArgumentException( "The scale must be a positive integer or zero");
  185.         }
  186.         BigDecimal b1 =  new BigDecimal(v1);
  187.         BigDecimal b2 =  new BigDecimal(v1);
  188.          return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
  189.     }
  190.      /**
  191.      * Provides accurate decimal rounding processing
  192.      *
  193.      * @param v     Number to be rounded
  194.      * @param scale How many decimal places are reserved
  195.      * @return Rounded results
  196.      */
  197.     public static double round(double v,  int scale) {
  198.          if (scale <  0) {
  199.             throw  new IllegalArgumentException( "The scale must be a positive integer or zero");
  200.         }
  201.         BigDecimal b =  new BigDecimal(Double.toString(v));
  202.          return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
  203.     }
  204.      /**
  205.      * Provides accurate decimal rounding processing
  206.      *
  207.      * @param v     Number to be rounded
  208.      * @param scale How many decimal places are reserved
  209.      * @return Rounded results
  210.      */
  211.     public static String round(String v,  int scale) {
  212.          if (scale <  0) {
  213.             throw  new IllegalArgumentException(
  214.                      "The scale must be a positive integer or zero");
  215.         }
  216.         BigDecimal b =  new BigDecimal(v);
  217.          return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
  218.     }
  219.      /**
  220.      * Remainder
  221.      *
  222.      * @param v1    Divisor
  223.      * @param v2    Divisor
  224.      * @param scale How many decimal places are reserved
  225.      * @return remainder
  226.      */
  227.     public static String remainder(String v1, String v2,  int scale) {
  228.          if (scale <  0) {
  229.             throw  new IllegalArgumentException(
  230.                      "The scale must be a positive integer or zero");
  231.         }
  232.         BigDecimal b1 =  new BigDecimal(v1);
  233.         BigDecimal b2 =  new BigDecimal(v2);
  234.          return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
  235.     }
  236.      /**
  237.      * Remainder    BigDecimal
  238.      *
  239.      * @param v1    Divisor
  240.      * @param v2    Divisor
  241.      * @param scale How many decimal places are reserved
  242.      * @return remainder
  243.      */
  244.     public static BigDecimal remainder(BigDecimal v1, BigDecimal v2,  int scale) {
  245.          if (scale <  0) {
  246.             throw  new IllegalArgumentException(
  247.                      "The scale must be a positive integer or zero");
  248.         }
  249.          return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
  250.     }
  251.      /**
  252.      * Compare size
  253.      *
  254.      * @param v1 Compared number
  255.      * @param v2 Comparison number
  256.      * @return If v1   Greater than v2   be   Return true   Otherwise false
  257.      */
  258.     public static boolean compare(String v1, String v2) {
  259.         BigDecimal b1 =  new BigDecimal(v1);
  260.         BigDecimal b2 =  new BigDecimal(v2);
  261.          int bj = b1.compareTo(b2);
  262.         boolean res;
  263.          if (bj >  0)
  264.             res =  true;
  265.          else
  266.             res =  false;
  267.          return res;
  268.     }
  269. }

Welcome to leave your views in the message area and discuss improvement together. If today's article gives you new inspiration, please forward it and share it with more people. Welcome to programmer Xiaole Technical exchange group , reply in the background“ Additive group ”Or“ study ”Just.

Guess you still want to see it

A collection of the latest interview questions from Ali, Tencent, Baidu, Huawei and JD

Using Intellij IDEA to solve the data flow problem of Java 8

Analysis of SpringBoot executable file for SpringBoot source code analysis

How to write the best Dockerfile? This article is for you, plain and clear!

Follow subscription number「Programmer Xiaole」,Watch more

 

Hey, are you watching?

Tags: Java

Posted on Wed, 01 Dec 2021 05:14:39 -0500 by Mark W