I understand that monetary values should be stored and processed as integers due to rounding error problems. That makes sense to me and I get it (I think).
But what about tax rates? Is there any reason a tax rate (not tax amount, tax rate, like 6.5 or 8.125) needs to be stored as an integer as opposed to a decimal?
And if I do store a tax rate as an integer, how do I apply the tax rate to the dollar amount in the transaction? If I do 10000 * 1.065 ($100.00 * 1.065) for a 6.5% tax rate, what would be the benefit of having stored that 6.5% in the database as 6500 as opposed to 6.500? I don't believe that multiplying or dividing a number by 100 one time is something that's susceptible to rounding errors.
Does it matter how I store tax rates?
First, it's not that you shouldn't use decimals. It's that you shouldn't use floating point where you want to have an exact value. Not all decimals are floating point; see the decimal datatype in C# or java.math.BigDecimal in Java.
Second, powers of 10 are especially susceptible to weird floating point issues because the way that floating point is implemented results in infinitely repeating decimals for division by powers of 10. See this question. Here's a trivial example:
groovy:000> f = 0.1F // make a floating point number
===> 0.1
groovy:000> f * 100
===> 10.000000149011612
This happens because the representation of 0.1 is a repeating decimal that gets truncated. Here the REPL lied, what is really in f isn't 0.1, it's 0.100000001490116119384765625.
You could round this and go on, there's an argument for doing that:
To resolve this issue, you need to provide appropriate rounding. With money this is easy as you know how many decimal places are appropriate and unless you have $70 trillion you won't get a rounding error large enough you cannot correct it.
But using BigDecimals:
groovy:000> d = new BigDecimal("0.1")
===> 0.1
groovy:000> d * 100
===> 10.0
Use a fixed point decimal so you know exactly what number you have. If your language doesn't have fixed decimals (like Javascript), you may have to fall back on integers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With