Do “Numbers retain specified decimal places” via BigDecimal

Requirements:

Keep the obtained Double type value to 2 decimal places without rounding

Proposal:

Precise number calculation and formatting with BigDecimal

public static void main(String[] args) {
        double num = 14.5684;
        int decimalPlaces = 2; // Reserve 2 digits

        BigDecimal bd = new BigDecimal(Double.toString(num));
        bd = bd.setScale(decimalPlaces, BigDecimal.ROUND_DOWN); // Keep 2 decimal places and do not do any translation, no matter how big the value is
        
        System.out.println(bd); // 14.56
    }

Note:

You must convert num to String type here, otherwise it will cause a loss of precision when using new BigDecimal().

Supplement:

About the use of BigDecimal constants ROUND_UP, ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_DOWN

ROUND_UP

If the truncated decimal is >0, round it up to one digit.

//ROUND_UP
        BigDecimal zero = new BigDecimal("1.0750000");
        BigDecimal one = new BigDecimal("1.0750001");
    
        BigDecimal two = zero.setScale(3,BigDecimal.ROUND_UP);
        BigDecimal three = one.setScale(3,BigDecimal.ROUND_UP);
 
        System.out.println("two=" + two); //two=1.075
        System.out.println("three=" + three); //three=1.076

ROUND_DOWN

Directly discard truncated decimals without rounding up the decimal place, no matter how big the discarded value is

 BigDecimal zero = new BigDecimal("1.0740000");
        BigDecimal one = new BigDecimal("1.0790001");
 
        BigDecimal two = zero.setScale(2,BigDecimal.ROUND_DOWN);
        BigDecimal three = one.setScale(2,BigDecimal.ROUND_DOWN);
        System.out.println("two=" + two);
        System.out.println("three=" + three);
 
        two=1.07
        three=1.07

ROUND_HALF_UP

Rounding, rounding in the mathematical sense

 BigDecimal zero = new BigDecimal("1.0740000");
        BigDecimal one = new BigDecimal("1.0790001");
 
        BigDecimal two = zero.setScale(2,BigDecimal.ROUND_HALF_UP);
        BigDecimal three = one.setScale(2,BigDecimal.ROUND_HALF_UP);
        System.out.println("two=" + two);
        System.out.println("three=" + three);
 
        two=1.07
        three=1.08

ROUND_HALF_DOWN

At first I thought this was rounding, but it wasn’t.

When the value of the truncated decimal place is >=5, and there is a value >0 after 5, it will be advanced by one digit.

 BigDecimal zero = new BigDecimal("1.0740001");
        BigDecimal one = new BigDecimal("1.075000");
        BigDecimal one1 = new BigDecimal("1.075001");
 
        BigDecimal two = zero.setScale(2,BigDecimal.ROUND_HALF_DOWN);
        BigDecimal three = one.setScale(2,BigDecimal.ROUND_HALF_DOWN);
        BigDecimal three1 = one1.setScale(2,BigDecimal.ROUND_HALF_DOWN);
        System.out.println("two=" + two);
        System.out.println("three=" + three);
        System.out.println("three1=" + three1);
 
        two=1.07
        three=1.07
        three1=1.08

Several pitfalls of BigDecimal

First.

When using the BigDecimal constructor, try to pass a string instead of a floating point type; secondly, if the first condition cannot be met, you can use the BigDecimal#valueOf method to construct the initialization value.

Second.

Normally, if you compare the sizes of two BigDecimal values, use the compareTo method implemented by them; if the precision of the comparison is strictly limited, you can consider using the equals method.

In addition, this scenario is more common when comparing 0 values, such as comparing BigDecimal(“0”), BigDecimal(“0.0”), BigDecimal(“0.00”). In this case, you must Use compareTo method for comparison.

Third.

When using BigDecimal for (all) operations, be sure to specify the precision and rounding mode explicitly.

For example:

 @Test
 public void test3(){
  BigDecimal a = new BigDecimal("1.0");
  BigDecimal b = new BigDecimal("3.0");
  BigDecimal c = a.divide(b, 2,RoundingMode.HALF_UP);
  System.out.println(c);
 }

Fourth.

Depending on the data result display format, different string output methods are used. The most commonly used method is toPlainString().

Here we need to understand the three methods of BigDecimal converting strings

toPlainString(): Does not use any scientific notation;

toString(): Use scientific notation when necessary;

toEngineeringString():Use engineering notation when necessary. Similar to scientific notation, except that the powers of the exponents are all multiples of 3, which is convenient for engineering applications, because many unit conversions are 10^3;

In addition, the format() method of the NumberFormat class can use BigDecimal objects as its parameters. BigDecimal can be used to format monetary values, percentage values, and general values that exceed 16 significant digits.

Usage examples are as follows:

NumberFormat currency = NumberFormat.getCurrencyInstance(); //Establish currency formatting reference
NumberFormat percent = NumberFormat.getPercentInstance(); //Create a percentage formatting reference
percent.setMaximumFractionDigits(3); //Maximum 3 decimal places for percentage
 
BigDecimal loanAmount = new BigDecimal("15000.48"); //Amount
BigDecimal interestRate = new BigDecimal("0.008"); //interest rate
BigDecimal interest = loanAmount.multiply(interestRate); //Multiply
 
System.out.println("Amount:\t" + currency.format(loanAmount));
System.out.println("Interest rate:\t" + percent.format(interestRate));
System.out.println("Interest:\t" + currency.format(interest));

The output is as follows:

Amount: ¥15,000.48
Interest rate: 0.8%
Interest: ¥120.00

—————-
Copyright Notice:

In the supplement, “About the use of BigDecimal constants” is reproduced from the original article of CSDN blogger “Did you see it°

Original link: https://blog.csdn.net/a229397620/article/details/125929156

Among the supplements, “Several Pitfalls of BigDecimal” are reproduced from the original article of CSDN blogger “Feifei Technology House

Original link: https://blog.csdn.net/m0_71777195/article/details/125970245