Difference and explanation of DecimalFormat digital formatting 0 and

  • 2021-11-29 06:49:11
  • OfStack

The catalogue first introduces the difference between "0" and "#" under 1. When "0" is used to fill the position, 2. When "#" is used to fill the position, it summarizes the exploration results of DecimalFormat data under 1, 4 rounding 5 into formatting processing problems

Let's first introduce the difference between "0" and "#" under 1

1. When filling the position with "0"

If the number is less, "0" will be filled, and decimals and integers will be filled;

If there are many numbers, cut them off, but only the end of decimals, integers cannot be cut;

At the same time, the decimal places that are cut off will be rounded by 4 and entered by 5.

2. When filling a place with "#"

If the number is less, it will not be processed, and "0" or "#" will not be filled;

If there are many numbers, cut them off, but only the end of decimals, integers cannot be cut;

At the same time, the decimal places that are cut off will be rounded by 4 and entered by 5.


public class PriceUtil { 
    public static String decimalFormat(float value) {
        DecimalFormat decimalFormat;
        decimalFormat = new DecimalFormat();
        decimalFormat.applyPattern("0.##");
        return decimalFormat.format(value);
    }
 
    public static String decimalFormat(double value) {
        DecimalFormat decimalFormat;
        decimalFormat = new DecimalFormat();
        decimalFormat.applyPattern("0.##");
        return decimalFormat.format(value);
    }
 
    public static String decimalFormat(String value) {
        if(value==null||value.isEmpty())
            return "0.00";
        double d = Double.parseDouble(value);
        DecimalFormat decimalFormat;
        decimalFormat = new DecimalFormat();
        decimalFormat.applyPattern("0.##");
        return decimalFormat.format(d);
    } 
}

Summary 1

1. "0" forces format alignment, and "#" is aligned in this format when it is most sufficient;

2. The applicable scenario of "#" is that when the decimal place exceeds two places, only two places are displayed, but there is only one place or no place, so there is no need to fill in "0";

3. It doesn't make sense to use multiple "#" for integer bits.

You can assemble what format you want to use.

DecimalFormat data is formatted by 4 rounding and 5 entering

In the recent development, the tested partner told me that there was a problem with one of the data with the same 4-shed and 5-input processing logic. At that time, I was forced. My handling method was like this. The business requirement was to keep two decimal places in 4 houses and 5 entries:


DecimalFormat d = new DecimalFormat("#0.00");
d.format(0.145d);

For this data, the expected result is 0.15, but the actual result is 0.14,,,,, why? Why?

Problem exploration

In this regard, all kinds of reasons for finding, finally a little eye-catching, here to do a general explanation, detailed reasons for small partners can refer to this article

1. DecimalFormat format data. If the method is not specified, it defaults to HALF_EVEN, but actually it should be HALF_UP; (HALF_EVEN is rounded to 5 (for example, 2.115 with two decimal places reserved), followed by a non-0 value to 1 (for example, 2.11500001 with two decimal places reserved is formatted as 2.12). If there is no number or all 0 after 5, it is rounded by even number before it, and it is rounded by 1 if it is odd number. The goal is to make the rounded 1 digit even. HALF_UP: True 4 rounded by 5)

2. When using BigDecimal, the parameters are passed in string as much as possible, which is more accurate than passing in double. Because the accuracy of double is easy to lose;

Results

In order not to change the code drastically, the data formatting was changed to use BigDecimal type:


DecimalFormat d = new DecimalFormat("#0.00");
d.setRoundingMode(RoundingMode.HALF_UP);
Double.valueOf(d.format(new BigDecimal(String.valueOf(0.145d))));

Related articles: