[Steven D'Aprano <steve@pearwood.info>]
Sure, for floats. I certainly wouldn't want to change the behaviour for floats. We could change the behaviour for ints (or at least we could if not constrained by backwards compatibility) or add a new function.
We could - but why would we? Just because a thing _can_ be done is no argument in fa\vor of doing so.
I was thinking more of Julia's rem(), which uses the sign of the dividend rather than the divisor.
Which is what most languages do (like also the current standards for C, C++, and Fortran; also what math.fmod() does). It's the natural result when using truncating division, and the latter is what _really_ drives it in most languages. They want integer division to truncate. "% (however spelled) returns the sign of the dividend" then _follows_ from preserving the identity: a = intdiv(a, b) * b + intmod(a, b) as already covered. (math.fmod() has a different motivation: so that x % y is always exact.) In Python, it's the opposite: the desire for intmod(a, b) to be positive when b is positive drove that integer division returns floor. As usual, if you want :"everything", install gmpy2 instead. mpz has 27(!) functions devoted to computing integer divisions and mods: https://gmplib.org/manual/Integer-Division The ones for unsigned ints aren't wrapped by gmpy2, since Python has no such distinct data type. The rest support your choice of truncating, floor, or ceiling division. However, not even mpz supports what the OP here appeared to want (non-negative mod regardless of inputs' signs). And neither does it support rounding division (which remainder() re\lies on). If something didn't even make it into mpz, it's a pretty safe bet that there's no compelling use case for it. Note that there are strong use cases for remainder() in the float world, but floats aren't ints.