Java, BigDecimal. Problems with division

gonso picture gonso · May 25, 2009 · Viewed 44.8k times · Source

I'm trying to calculate a percentage "factor". That is, given a 20%, convert it into 0.2 (my intention is to later multiply values by that and get the 20% of the values).

Anyway, the question is related with this piece of code:

public static void main(String[] args) {
    int roundingMode = BigDecimal.ROUND_FLOOR;
    BigDecimal hundred = new BigDecimal("100");
    BigDecimal percentageFactor = null;
    BigDecimal percentage = new BigDecimal("20");
    BigDecimal value = new BigDecimal("500");
    percentageFactor = percentage.divide(hundred, roundingMode);
    float f = percentage.floatValue() / hundred.floatValue();
    f = value.floatValue() * f;
    BigDecimal aux = value.multiply(percentageFactor);
    System.out.println("factor:"+percentageFactor.toString());
    System.out.println("final falue:"+aux.toString());
    System.out.println("Float Value:"+f);       
}

I would expect the outcome of this to be something like:

factor: 0.2
final value: 100
float value: 100

but instead percentage.divide(hundred, roundingMode); is returning zero, an hence I get:

factor:0
final falue:0
Float Value:100.0

What am I doing wrong? How can I divide two big decimals properly?

By the way, I'm using BigDecimal because I will be calculating monetary percentages, so I want control regarding rounding.

Answer

KarlP picture KarlP · May 25, 2009

I think that the best solution is to set the requested scale when dividing: In this case perhaps 2.

    BigDecimal hundred = new BigDecimal(100);
    BigDecimal percentage = new BigDecimal(20);
    BigDecimal value = new BigDecimal(500);
    BigDecimal percentageFactor =
                 percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP);

    value = value.multiply(percentageFactor);
    System.out.println("final value:"+ value);

final value 100.00

(Multiplication is using the scale from the factors (0+2) but it can be specified too.)

I'd use HALF_UP for accounting (in my legislation) or EVEN (for statistics) for rounding mode.