Search code examples
javabigdecimal

How to calculate the ratios of values to their sum?


I have 3 BigDecimal values and I want to find 3 values that represent its ratio to their sum and those ratios should add up to 1. However, I'm running into the following error:

BigDecimal a = new BigDecimal("19000.0000");
BigDecimal b = new BigDecimal("31000.0000");
BigDecimal c = new BigDecimal("999901467.88");

BigDecimal sum = a.add(b).add(c); //999951467.8800

BigDecimal aRatio = a.divide(sum, 4, BigDecimal.ROUND_HALF_UP); //returns 0.0000
BigDecimal bRatio = b.divide(sum, 4, BigDecimal.ROUND_HALF_UP); //returns 0.0000
BigDecimal cRatio = c.divide(sum, 4, BigDecimal.ROUND_HALF_UP); //returns 0.9999

/** returns 0.9999 doesn't equal to 1! **/
BigDecimal totalRatio = aRatio.add(bRatio).add(cRatio);

As you can see the sum of the 3 ratios does not add up to 1. I can change the scale from 4 to 5 and that will fix the issue. However I'm using the same code above to calculate other different numbers. So I'm trying to find a proper approach that will work for any X ratios with any numbers.


Solution

  • As soon as you use rounding, you effectively agree to have results that are not absolutely correct. So, if the goal is to have the sum of the ratios equal to 1, just do

    BigDecimal aRatio = a.divide(sum, 4, BigDecimal.ROUND_HALF_UP); 
    BigDecimal bRatio = b.divide(sum, 4, BigDecimal.ROUND_HALF_UP); 
    BigDecimal cRatio = BigDecimal.ONE.subtract(aRatio.add(bRatio));