I don't mean a tiny precision error, I mean a completely "wrong" result, for a harmless-looking calculation:
expected: 1.7306687640440686
got: 0.08453630115074517
The calculation (Try it online!):
from math import pi
a = 60.9
mod = 2 * pi
print('expected:', a**2 % mod)
print('got: ', (a % mod)**2 % mod)
The second calculation above uses a % mod
before squaring. With integers, when we want to modulo at the end anyway, such early modulos are a well-known and often-used way to keep intermediate results small (to avoid overflow of fixed-size ints or slowness of arbitrary-size ints). With floats, I expected a small precision error but got entirely different results. Even for the above example of moduloing before a simple squaring.
Why do I get a completely "wrong" number with floats, when the same technique works perfectly for ints?
Writing "wrong" in quotes because most certainly it's my expectation that's wrong, not the result. Though apparently I'm not the only one with that expectation (which is why I found it useful enough to point out as question and hopefully an answer): This came from another question's comment suggesting to "implement your own fast exponentiation with modulo in each iteration", which got five upvotes, two answers implementing that, four upvotes for those answers, and nobody batted an eye about this severe issue even though people did point out precision worries about it (which don't even matter). (I also tried it, utterly failed, even for small exponents, and my above snippet is what I reduced / tracked down the problem to).