问题
For accounting program I need to divide a price by 3 so it can be shared over 3 months
For example 9€
- 3€ first month
- 3€ second month
- 3€ third month
Now this would be price/3
But what if the number is 10?
- 3,33€ first month
- 3,33€ second month
- 3,33€ last month
3,33€*3 =€9.99
One cent has gone missing. How can I make it so the ouput would become 3,33€ , 3,33€ , 3,34€?
回答1:
As Bathsheba said, ask your users first.
Here's a technique that I've used often in such scenarios. This method will ensure the most even distribution, with the upward bias toward the end. For example, if you call DivvyUp(101, 3)
, you'll get 33.66, 33.67, 33.67
. Notice that the difference isn't just made up for at the end. Instead, each value is computed according to what's left, not what was started with.
public static double[] DivvyUp(double total, uint count)
{
var parts = new double[count];
for (var i = 0; i < count; ++i)
{
var part = Math.Truncate((100d * total) / (count - i)) / 100d;
parts[i] = part;
total -= part;
}
return parts;
}
回答2:
You need to ask the accountant what they would want here. That's an important thing to do in software development: ask the users.
Normally, for stability, you would subtract the amounts paid from a balance account, and put checks in to ensure that the balance falls to zero.
And don't ever use a floating point data type when building accounting software. Floating point precision will bite you. Use a currency type instead.
回答3:
You could set the last by making up the difference, instead of via the same calculation as the rest. In pseudocode:
normalMonthPrice = RoundToTwoPlaces(totalPrice / months);
lastMonthPrice = totalPrice - (normalMonthPrice * (months - 1));
回答4:
Congratulations, you've found out why the computing world isn't as simple as "put math on it"-
The easiest solution would be to divide by 3, round to two decimal places, and use that value for the first two months, and original - 2 * perMonth
for the rest.
来源:https://stackoverflow.com/questions/21914074/dividing-prices-by-3