Alexander Kuzmenko
Alexander Kuzmenko

Reputation: 537

Java BigDecimal formatting

I have a class with BigDecimal field. I put this object to JSP (Spring MVC). And I need to display BigDecimal field without zero in decimal (20.00 like 20), that's why my getter method looks like

public BigDecimal getValue() {
    return value.stripTrailingZeros();
}

And I have the next result:

20.50 = 20.5;
13.25 = 13.25;
30.00 = 3E+1.

How can I change 3E+1 to 30 ? Can I format it with Java or JSTL?

Upvotes: 1

Views: 6248

Answers (3)

Alexander Kuzmenko
Alexander Kuzmenko

Reputation: 537

I found a simple solution. It doesn't need to do stripTrailingZeros() in the getter method. Just

public BigDecimal getValue() {
    return value;
}

And on the JSP

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<fmt:formatNumber value="${object.value}" minFractionDigits="0"/>

Upvotes: 3

user2533521
user2533521

Reputation: 236

I think you can get away with just using toPlainString() on the returned bigdecimal.

Simple testing program:

    BigDecimal[] bds={new BigDecimal("1.0"),new BigDecimal("20.50"), 
              new BigDecimal("13.25"), 
              new BigDecimal("30.0"),
              new BigDecimal("30.01000"), new BigDecimal("0.0000")
    };
    for (BigDecimal bd: bds)
        System.out.println(bd+"==>"+bd.stripTrailingZeros().toPlainString());

returns:

  1.0==>1
  20.50==>20.5
  13.25==>13.25
  30.0==>30
  30.01000==>30.01
  0.0000==>0.0000

There is only one boundary case that i know that it doesn't work for..and that is all variants of 0.

  0.0 => 0.0
  0.00 => 0.00

I believe this is covered in this stack overflow article: Why does new BigDecimal("0.0").stripTrailingZeros() have a scale of 1? As per the article, this is corrected in java 8 (but i haven't tested it yet).

You can get away with it by doing a compareTo(BigDecimal.ZERO)==0 and using BigDecimal.ZERO in that case.

BigDecimal[] bds={new BigDecimal("1.0"),
                  new BigDecimal("20.50"),
                  new BigDecimal("13.25"),
                  new BigDecimal("30.0"),
                  new BigDecimal("30.01000"), 
                  new BigDecimal("0.0000")
    };
    for (BigDecimal bd: bds){
        if (bd.compareTo(BigDecimal.ZERO) == 0){
            System.out.println(bd+"=>"+BigDecimal.ZERO);
        }
        else {
            System.out.println(bd+"==>"+bd.stripTrailingZeros().toPlainString());
        }

returns:

  1.0==>1
  20.50==>20.5
  13.25==>13.25
  30.0==>30
  30.01000==>30.01
  0.0000=>0

Upvotes: 2

Kleyguerth
Kleyguerth

Reputation: 101

If you can control the formatting method from BigDecimal to String (the framework is displaying the string returned from BigDecimal.toString()), you can use NumberFormat for better control of the displayed string.

According to the Spring documentation, you can implement a custom formatter for that job.

I suggest you to override the default NumberFormatter and override the print method, like so:

public class NoZeroesBigDecimalFormatter extends org.springframework.format.number.NumberFormatter{
    @Override
    public String print(Number number, Locale locale) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(5); //whatever value is your maximum displayed digits
        return nf.format(value);
    }
}

Then, see how you can bind that formatter to your field.

Upvotes: 0

Related Questions