Earlier quoted context omitted.
The trick is that by default rounding happens using banker's rounding. Programming languages use this because this is what CPUs use. When you want to round your way, you need an extra digit and round manually: def tax_f4(amt, rate): tax = round(amt * rate * 1000) return tax // 10 + (tax % 10 > 4)
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.
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.