How to display a number with always 2 decimal points using BigDecimal?
Asked Answered
A

8

48

I am using BigDecimal to get some price values. Requirement is something like this, what ever the value we fetch from database, the displayed valued should have 2 decimal points.

Eg:

fetched value is 1 - should be displayed as 1.00
fetched value is 1.7823 - should be displayed as 1.78

I am using setScale(2, BigDecimal.ROUND_HALF_UP) but still some places, if the data from DB is a whole number then the same is being displayed !!

I mean if the value is 0 from DB its displayed as 0 only. I want that to be displayed as 0.00

Thanks

Apologue answered 25/1, 2013 at 5:1 Comment(3)
I think you can find your answer right here: https://mcmap.net/q/181136/-how-do-i-format-a-number-in-javaRecur
thanks daniel :)that was too fast reply.. but i am already using the bigdecimal.round_half_up with setscale(2) it works when u have number like 2.12 or 4.2343. when the value is a whole number like just 2 then i want that to be displayed as 2.00 and this is where i am failing !!Apologue
possible duplicate of How do I format a number in java?Yucca
R
70

BigDecimal is immutable, any operation on it including setScale(2, BigDecimal.ROUND_HALF_UP) produces a new BigDecimal. Correct code should be

BigDecimal bd = new BigDecimal(1);
bd.setScale(2, BigDecimal.ROUND_HALF_UP); // this does change bd
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(bd);

output

1.00

Note - Since Java 9 BigDecimal.ROUND_HALF_UP has been deprecated and you should now use RoundingMode.ROUND_HALF_UP.

Ravenna answered 25/1, 2013 at 5:11 Comment(2)
This is deprecated since Java 9, use .setScale(2, RoundingMode.HALF_UP);Planetarium
I think he meant "this DOES NOT change bd". The second line is not necessaryValenzuela
C
15

you can use the round up format

BigDecimal bd = new BigDecimal(2.22222);
System.out.println(bd.setScale(2,BigDecimal.ROUND_UP));

Hope this help you.

Coppock answered 25/1, 2013 at 5:20 Comment(0)
E
14

To format numbers in JAVA you can use:

 System.out.printf("%1$.2f", d);

where d is your variable or number

or

 DecimalFormat f = new DecimalFormat("##.00");  // this will helps you to always keeps in two decimal places
 System.out.println(f.format(d)); 
Entrepreneur answered 25/1, 2013 at 5:25 Comment(1)
Better to use new DecimalFormat("##0.00");, because with ##.00 for 0 you will get .00 instead of 0.00Pomposity
B
2

You need to use something like NumberFormat with appropriate locale to format

NumberFormat.getCurrencyInstance().format(bigDecimal);
Brittain answered 25/1, 2013 at 5:5 Comment(1)
This will print the currency symbol, e.g. $, along with the number, which the OP did not mention he wanted. But like the thought of using the currency instance here for readability.Mogerly
N
2

BigDecimal.setScale would work.

Niobous answered 21/10, 2013 at 4:5 Comment(0)
K
0

The below code may help.

protected String getLocalizedBigDecimalValue(BigDecimal input, Locale locale) {
    final NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
    numberFormat.setGroupingUsed(true);
    numberFormat.setMaximumFractionDigits(2);
    numberFormat.setMinimumFractionDigits(2);
    return numberFormat.format(input);
}
Krissy answered 27/1, 2020 at 12:22 Comment(0)
E
0

You can use a custom annotation in this manner: The custom annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FormatBigDecimal {
    String format() default "0.00";
}

And then you can apply the annotation on a field and in the constructor call the implementation method as shown below:

public class TestClass {
   

    @FormatBigDecimal
    private BigDecimal myDecimal;
    public TestClass(BigDecimal myDecimal) throws ParseException, IllegalAccessException {
        this.myDecimal = myDecimal;
        formatBigDecimalFields();
    }

    public void setMyDecimal(BigDecimal myDecimal) {
        this.myDecimal = myDecimal;
    }

    public BigDecimal getMyDecimal() {
        return myDecimal;
    }
/**
In the above method, we are using reflection to get all the fields declared in the class. Then, we are iterating over all the fields and checking whether the @FormatBigDecimal annotation is present on the field. If it is present, we are making the field accessible and getting its value.

We are also getting the format string from the @FormatBigDecimal annotation and using it to create a DecimalFormat object with the desired format. Then, we are formatting the value of the field using the DecimalFormat object and storing the formatted value in a string.

Finally, we are parsing the formatted value back into a BigDecimal object and setting it as the value of the field.
**/
    public void formatBigDecimalFields() throws IllegalAccessException, ParseException {
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field.isAnnotationPresent(FormatBigDecimal.class)) {
                field.setAccessible(true);
                BigDecimal value = (BigDecimal) field.get(this);
                FormatBigDecimal formatAnnotation = field.getAnnotation(FormatBigDecimal.class);
                String formatString = formatAnnotation.format();
                NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
                DecimalFormat decimalFormat = (DecimalFormat) format;
                decimalFormat.applyPattern(formatString);
                String formattedValue = decimalFormat.format(value);
                BigDecimal formattedDecimal = new BigDecimal(formattedValue);
                field.set(this, formattedDecimal);
            }
        }
    }

}

To Use it:

 TestClass testClass = new TestClass(new BigDecimal("10000.899"));
        System.out.println(testClass.getMyDecimal());

will give: 10000.90

Erv answered 20/2, 2023 at 9:12 Comment(0)
H
0

The use of .setScale(2, BigDecimal.HALF_UP); has been deprecated.

From Java 9 and onwards please use .setScale(2, RoundingMode.HALF_UP);

   double val = 9;
   var convertedVal = BigDecimal.valueOf(val).setScale(2, RoundingMode.HALF_UP);
Heilbronn answered 23/6, 2024 at 1:4 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.