Storing currency into a floating-point type seem to be the most intuitive thing to do, especially most major currency are displayed as fraction to the cents, eg: $10.50. However floating-point is designed to store fraction up into specific precision, but currency is only subdivisible until a certain amount. For example the smallest fraction is US Dollar is 1 cent, Australian Dollar 5 cent and so on. Hmm, now it sounded like storing them as integer made much more sense!
Here’s one problem I came accross recently: split a sum of money proportionally into N people. That sounded simple, until I realize if the sum cannot be divided equally, you need to take into account roundings and who get lucky to receive the remainder.
For example: divide $10 into 3 people. Each person will get $31/3.. but the problem is there isn’t any $1/3 in real life (at least in all dollar currencies I know of).
At first.. I thought I can implement the code like this:
double amount = 10.0; double person_a = amount / 3.0; double person_b = amount / 3.0; double person_c = amount / 3.0; printf("person a: $%.2f\n", person_a); // This prints the double value rounded to 2 digits after decimal printf("person b: $%.2f\n", person_b); printf("person c: $%.2f\n", person_c);
But this code gives me
person a: $3.33 person b: $3.33 person c: $3.33
Hey the total is only $9.99 where do the 1 cent go?
Obviously this is a rounding problem. 10.0 / 3.0 gives 3.3333333… (up until the limit of double precision), but when rounded into 3.33, we lost 0.0033333…..
Probably a more appropriate code to solve this problem is as follows:
int amount = 1000; // <– That is 1000 cents, ie: 10 dollar int remainder = 1000 % 3; int person_a = amount / 3; int person_b = amount / 3; int person_c = amount / 3; printf(“person a: %.2f\n”, person_a / 100.0); printf(“person b: %.2f\n”, person_b / 100.0); printf(“person c: %.2f\n”, person_c / 100.0); printf(“$%.2f remaining, who’s the lucky person?\n”, remainder / 100.0); [/c] Which gives: [text] person a: $3.33 person b: $3.33 person c: $3.33 $0.01 remaining, who’s the lucky person? [/text]