Search code examples
jsfbigdecimaljsf-2.2

BigDecimal arithmetic on JSF pages


For example, given below a JSF managed bean.

@ManagedBean
@ViewScoped
public final class Bean implements Serializable {

    private BigDecimal price; //Getter only.
    private BigDecimal currencyRate; //Getter only.
    private static final long serialVersionUID = 1L;

    @PostConstruct
    private void init() {
        price=new BigDecimal(5678);
        currencyRate=new BigDecimal(0.016622);
    }
}

Multiplication of price and currencyRate can be displayed on <h:outputText>.

<h:outputText value="#{bean.price * bean.currencyRate}"/>

Does this multiplication yield BigDecimal or it is simply a double value?


In other words, is this equivalent to the following?

<h:outputText value="#{bean.price.multiply(bean.currencyRate)}"/>

It displays 94.3797160000000077070825277303356415359303355216979980468750 in both the cases.


And what if when there is a converter to display a specified number of decimal digits, two for example as follows?

<h:outputText value="#{bean.price * bean.currencyRate}"
              converter="#{bigDecimalConverter}"/>

I want the result of such expressions to be BigDecimal anyway.


Solution

  • From El 3.0 spec pdf (page 13 - section 1.7.1):

    The evaluation of arithmetic operators is described in the following sections. A and B are the evaluation of subexpressions.

    1.7.1 Binary operators - A {+,-,*} B

    • If A and B are null, return (Long)0
    • If A or B is a BigDecimal, coerce both to BigDecimal and then:
      • If operator is +, return A.add(B)
      • If operator is -, return A.subtract(B)
      • If operator is *, return A.multiply(B)
    • If A or B is a Float, Double, or String containing ., e, or E:
      • If A or B is BigInteger, coerce both A and B to BigDecimal and apply operator.
      • Otherwise, coerce both A and B to Double and apply operator
    • If A or B is BigInteger, coerce both to BigInteger and then:
      • If operator is +, return A.add(B)
      • If operator is -, return A.subtract(B)
      • If operator is *, return A.multiply(B)
    • Otherwise coerce both A and B to Long and apply operator
    • If operator results in exception, error

    Therefore, yes the EL expression #{bean.price * bean.currencyRate}" as specified in <h:outputText>,

    <h:outputText value="#{bean.price * bean.currencyRate}"/>
    

    is evaluated to a java.math.BigDecimal, since both bean.price and bean.currencyRate in the corresponding backing bean are of type java.math.BigDecimal - bean.price.multiply(bean.currencyRate) is performed internally.