Pit and solution of BigDecimal of Java

  • 2021-12-12 04:36:34
  • OfStack

Catalog Java BigDecimal pit mining pit cause is the solution BigDecimal easy to appear pit

Pit of Java BigDecimal

Mining pit


    BigDecimal bd =new BigDecimal(0.1);
    System.out.println(" The result is: " + bd);
     The result is: 158.740000000000009094947017729282379150390625

The reason is

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

2) The String constructor is completely predictable: Writing newBigDecimal ("0.1") creates an BigDecimal, which is exactly equal to the expected 0.1. Therefore, in comparison, it is generally recommended to use the String constructor first.

3) When double must be used as the source of BigDecimal, note that this constructor provides an exact transformation; It does not provide the same result as using the Double. toString (double) method first and then the BigDecimal (String) constructor to convert double to String. To get this result, use the static valueOf (double) method.

Solution

1.


   BigDecimal loanAmount = new BigDecimal("15000.48"); 
   System.out.println(" Format before conversion: " + loanAmount);
    The result is: format before conversion: 15000.48

2.


 NumberFormat currency = NumberFormat.getCurrencyInstance(); //  Create currency formatting reference  
 NumberFormat percent = NumberFormat.getPercentInstance(); //  Create a percentage formatted reference  
 percent.setMaximumFractionDigits(3); //  The percentage has the most decimal points 3 Bit  
 BigDecimal loanAmount = new BigDecimal("15000.48"); //  Loan amount 
 System.out.println(" Format before conversion: " + loanAmount);
 BigDecimal interestRate = new BigDecimal("0.008"); //  Interest rate    
 BigDecimal interest = loanAmount.multiply(interestRate); //  Multiplication 
 System.out.println(" Loan amount :\t" + currency.format(loanAmount));
 System.out.println(" Interest rate :\t" + percent.format(interestRate));
 System.out.println(" Interest :\t" + currency.format(interest));
 BigDecimal bd = new BigDecimal(158.74);
 System.out.println(" The result is: " + bd);   

BigDecimal Pits Easily Occurred

BigDecimal1 is generally used to do high-demand accurate calculation. A few days ago, I encountered a big pit when I was using it. Record it.

This problem arises from the use of BigDecimal for division (divide). The divide method of this class has three commonly used constructors.

BigDecimal divide(BigDecimal divisor) Returns a BigDecimal whose value is (this / divisor), and whose preferred scale is (this.scale() - divisor.scale()); if the exact quotient cannot be represented (because it has a non-terminating decimal expansion) an ArithmeticException is thrown.
BigDecimal divide(BigDecimal divisor, int roundingMode) Returns a BigDecimal whose value is (this / divisor), and whose scale is this.scale().
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) Returns a BigDecimal whose value is (this / divisor), and whose scale is as specified.

In the first constructor, you can pass in only the dividend (divisor).

However, it is very easy to make an error when calling this method. When the division is endless, an infinite circulating decimal will be generated, and an exception will be thrown at this time:

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

at java.math.BigDecimal.divide(BigDecimal.java:1690)

In the second or third constructor, it is specified that when the division is inexhaustible, the significant digits are reserved, so it is safer.

It is recommended to use the third method when using this method, which is safer.


Related articles: