Java, BigDecimal. Problems with division

48,538

Solution 1

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

    var hundred = new BigDecimal(100);
    var percentage = new BigDecimal(20);
    var value = new BigDecimal(500);
    
    var percentageFactor = 
        percentage.divide(hundred,2, BigDecimal.ROUND_HALF_UP);
    
    value = value.multiply(percentageFactor);
    System.out.println("final value:"+ value);

Final value: 100.00

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

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

Solution 2

The scale of new BigDecimal("20") is zero because you've got no decimal point in there. That means that your percentage.divide(hundred, BigDecimal.ROUND_FLOOR) will produce zero (it's effectively int(20/100) or 0).

If you really want to do fractional stuff, use new BigDecimal("20.00") so the scale is set correctly, or use one of the other constructors to set the scale specifically.

Here's the output from that simple change of 20 to 20.00, complete with your spellink misteak :-)

factor:0.20
final falue:100.00
Float Value:100.0
Share:
48,538
gonso
Author by

gonso

Updated on May 27, 2021

Comments

  • gonso
    gonso almost 3 years

    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.