# Function that divides money with regard to the smallest denomination

I'm writing a function divideMoney that takes the value of a sum of money and divides it according to some percentages, then rounds each division to the nearest denomination.

For example:

//divideMoney(sum, percentages, denomination);

divideMoney(102, [0.5, 0.30, 0.20], 0.25);


This should divide the sum of $102 to 3 divisions, first is 50% ($51), second is 30% ($30.6) and the third is 20% ($20.4).

But because the smallest accepted denomination is the quarter ( 0.25 ), so $30.6 should be$30.50 instead, and $20.40 should be$20.50 as well. So the expected result is [51, 30.5, 20.5].

Here is what I tried

Original Code

function divideMoney(sum, percentages, denomination) {
var result, diff, resultSum;
result = [];
diff = 0;
percentages.forEach(function (percent) {
var div, fraction, mod;
div = (percent * sum) + diff;
fraction = div - Math.trunc(div);
if (fraction > 0) {
mod = fraction % denomination;
diff += mod;
div -= mod;
}
result.push(div);
});
resultSum = result.reduce(function(a, b){ return a + b; }, 0);
if (resultSum < sum) {
result.push(sum - resultSum);
}
return result;
}


Update (fix rounding)

function divideMoney(sum, percentages, denomination) {
var result = [], remainder = sum, part, i;
for(i = 0; i < percentages.length - 1; i++) {
part = percentages[i] * sum;
if (part % 1) {
part = Math.round(part/denomination)*denomination;
}
remainder -= part;
result.push(part);
}
result.push(remainder);
return result;
}

• Does your code work as expected? It sounds like it's not doing what it should. – Pimgd Mar 3 '16 at 11:11
• I think it works well in many straightforward cases, however I'm not sure. – KeyBored Mar 3 '16 at 11:52
• Add more unit tests and cover boundary conditions. – Frank C. Mar 3 '16 at 12:15
• Ah yes, I can see in your code you do things with denomination and modulus, from the way I read your question it was like "it divides properly but doesn't handle denomination properly" – Pimgd Mar 3 '16 at 12:39
• I'm puzzled by the method: when a primarily computed percentage does not match denomination, it's always decreased to the next one down. Shouldn't be rather increased/decreased to the closer one, like it usually apply when rounding? – cFreed Mar 3 '16 at 12:57

I can make infinite money (well, as much as will fit in a javascript number) with your code!

var money = 10;
while(true){
money = divideMoney(money, [3, 0], 1)[0];//muhahahahah infinite money
}


Which divides the money like so: 1 for me, 1 for myself, 1 for I, none for you. 1 for me...

I'd recommend in this case to fall back on relative percentages: that is, sum the percentages and then set the cut to be the percentage of the summed percentage. So 10, 5, 5 = 20 total, 10/20 = 0.5, 5/20 = 0.25, so it's 0.50, 0.25, 0.25.

• Thanks for your answer but in my case I always assume that the provided inputs are valid, so I don't need to validate the inputs. – KeyBored Mar 3 '16 at 13:58
• The percentages array will always contain values between 0 and 1 (exclusively), and their sum will be always 1. – KeyBored Mar 3 '16 at 14:00