
[Steven D'Aprano <steve@pearwood.info>[\
Alas, math.remainder goes through float:
math.remainder(3**500, 3) # Should be 0. 1.0 math.remainder(3**500 + 2, 3) # Should be 2. 1.0
You mean -1 here: remainder() returns a member of the equivalence class with least absolute value, and abs(-1) < abs(2).
It would be nice if remainder() worked properly for exact values, without overflow or rounding errors.
I don't think so, It's required by 754-like standards explicitly for floating-point values. In that way, it's much too like math.fmod:
import math math.fmod(10**300, 100) 60.0
That's intended. And, of course, so is this:
math.remainder(10**300, 100) -40.0
It's far more important that remainder() work similarly to fmod() than that remainder() implement some bigint function nobody wants ;-) Seriously, modulus for floating point is overwhelmingly used as part of argument-reduction steps. Indeed, almost the entire actual point to it is that 0 <= remainder(x, y) <= abs(y) / 2.0 so that it leaves behind "a remainder" of magnitude as small as possible, which in floating point algorithms can greatly speed convergence of following approximations.
... I don't know whether this counts as compelling or not, but I have a divmod variant which returns an always positive modulus for use in base conversion. It is only used in one place in a module I haven't touched in a decade, so it is quite possible that if I were writing that code again today, I wouldn't do it that way.
Insufficient information to guess from here. If; you're mucking around with negative bases, no, I expect that's too exceedingly niche to count as compelling. But if you're doing % with a positive base, the % result Python returns right now is already always non-negative.