That works for 10% of \$21.15, giving the desired 212.However, for 10.14% of \$21.15, it gives 215, but it should be 214. Another example is 3.5% of \$60.70, for which it gives 213 but correct is 212.

 You're right. My remainder calculation in my code snippet is incorrect. It should've been a floating point remainder instead.`````` import math def tax_f5(amt, rate): t = amt * rate * 1000 return round(t) // 10 + ((math.fmod(t, 10.0) - 5.0) > -1e-7) `````` But then since there's now an epsilon, it raises the question of how many digits of precision the tax rates typically need. This is indeed a difficult problem.
 Some exhaustive testing on all amounts from \$0.01 through \$999.99 in \$0.01 increments and all taxes from 0.01% through 99.99% in increments of 0.01% show that this is the minimum that does the trick (switching to C from Python for speed):`````` unsigned long tax = (unsigned long)round(amt * rate * 1000000); return tax/(10000) + (fmod(tax, (double)(10000)) - (double)(5000) > -1e-5 ? 1 : 0); `````` (Yes, I see that I goofed in translation your code to C and typed -1e-5 instead of -1e-7. It looks like the results are the same with -1e-7).I also tested that up through \$9999.99 with taxes up to 12%, and no problems.Adding another 0 to the 1000000, the two 10000's, and the 5000 works. And another, and another. Past that it starts to fail, but not the simple off-by-one failures you get when you don't use enough digits. These are way way off, so I'm guessing its running into some new class of problem. I haven't looked to see what that is yet.

Search: