How to correctly calculate forward and backward percentage in Java by BigDecimal?

Viewed 75

There is mismatch between two results, which are got when I try to calculate percentage having initial summa (let's say - forward commission) and adjusted summa (let's call this backward commission).

So let me have 25 as initial value.

I'd like to calculate 3.5%.

What am I doing for this?

P = 25 - 25*(1-3.5/100) = 0.875.

In terms of Java it looks like this

where initValue equals 25 for sure, and percent equals 3.5

    initValue.subtract(initValue.multiply(BigDecimal.ONE.subtract(percent.scaleByPowerOfTen(-2)).setScale(2, RoundingMode.HALF_UP));

result = 0.87 given by Java

Let me substract this from 25. My final result is 24.13.

So let's assume that I need to calculate backward commission from this summa 24.13

24.13/(1 - 3.5/100)

and this gives me 0.88 when I use Google Sheet and the following Java code:

updatedValue.divide(BigDecimal.ONE.subtract(percent.scaleByPowerOfTen(-2)), RoundingMode.HALF_UP).subtract(updatedValue).setScale(2, RoundingMode.HALF_UP);

where updatedValue equals 24.13 and percent still 3.5

Basically since mathematical context seems to me as doubtless should I expect that my backward commission give me 0.87 ? And why I get 0.88 constantly then ?

1 Answers

In java.math RoundingMode.HALF_UP means "Rounding mode to round towards nearest neighbor unless both neighbors are equidistant, in which case round up". Since you are calculating money I recommend you to make the rounding operations at the end of the calculation.

initValue.subtract(initValue.multiply(BigDecimal.ONE.subtract(percent.scaleByPowerOfTen(-2))).setScale(2, RoundingMode.HALF_UP);

This will actually give you the same result 0,87.

When you calculate the backward commission it is best to change the rounding mode since it is a backward operation. So the code will be:

updatedValue.divide(BigDecimal.ONE.subtract(percent.scaleByPowerOfTen(-2)), RoundingMode.HALF_DOWN).subtract(updatedValue).setScale(2, RoundingMode.HALF_DOWN);

This will give you the same result 0,87.

Related