Twice this week, I’ve run into bugs in programs caused by not accounting for doing math with floats.
Floats are a numerical data type used by computers when there is a decimal or fraction involved in the number.
For somewhat arcane reasons I won’t go into here, computers frequently end up just a smidge off when they try to do math with these.
As it happened both instances of the errors were happening when dealing with adding and subtracting money amounts. The program was looking for a certain amount to go to zero as a condition to end a loop. Comparing the condition against the result of the floating point calculation came out to some small, but not zero amount, $0.000000000099995, or something. Since it’s not zero, the loop wouldn’t terminate.
Here are a couple quick ways to deal with these small remnants of cents (or whatever fractions) when you come across them. (Hat tip to Bernhard Breytenbach.)
- When calculating with money, convert everything to cents before you start, then do the calculations with integers. Convert back to dollars (or whatever) when you’re done.
- After doing floating point calculations, you can cut off the long tails of the decimals by rounding (most languages have the capacity for rounding) the number times 10 to the power of however many decimal places you want to keep, then dividing the rounded number by that same power of 10.
So, for example, if you have
n = 8.22222222222244444 and you want 2 decimal places:
round (n * 100) / 100
round (822.2222222244444) / 100 == 822 / 100 == 8.22
Round as late as possible though. If you still have more calculations to do, you’ll end up wasting a lot of cycles rounding.