46

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

informatik01
  • 16,038
  • 10
  • 74
  • 104
user1391730
  • 461
  • 1
  • 4
  • 3
  • 1
    I think you can find your answer right here: http://stackoverflow.com/a/50543/61624 – Daniel Kaplan Jan 25 '13 at 05:02
  • 2
    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 !! – user1391730 Jan 25 '13 at 05:05
  • possible duplicate of [How do I format a number in java?](http://stackoverflow.com/questions/50532/how-do-i-format-a-number-in-java) – Bhavesh Patadiya Jan 25 '13 at 06:09

7 Answers7

69

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.

blacktide
  • 10,654
  • 8
  • 33
  • 53
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
14

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.

Mr.vicky patel
  • 1,839
  • 1
  • 9
  • 18
corgrin
  • 255
  • 1
  • 2
  • 12
13

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)); 
2

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

NumberFormat.getCurrencyInstance().format(bigDecimal);
kosa
  • 65,990
  • 13
  • 130
  • 167
  • 3
    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. – pierus Dec 15 '15 at 15:36
2

BigDecimal.setScale would work.

Jackie
  • 25,199
  • 6
  • 33
  • 24
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);
}
Narasimha A
  • 319
  • 5
  • 14
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

Brian Brix
  • 449
  • 4
  • 12