Rust's rem_euclid is still wrong for negative moduli. To see why, remember that we want n = remainder + quotient * divisor. Now look at the horrible mess that is div_euclid:
> In other words, the result is self / rhs rounded to the integer q such that self >= q * rhs. If self > 0, this is equal to round towards zero (the default in Rust); if self < 0, this is equal to round towards +/- infinity.
Python gets it right. Division is simply flooring division, and modulo is defined to satisfy n = remainder + quotient * divisor. That immediately gets you all the nice behavior such as (-1) % 10 = 9, and 1 % -10 = -9.
The operator precedence is wrong on the second one: to take -1 mod 10, you'd want to write (-1_u32).rem_euclid(10), which gives the expected result of 9.
Because always returning a positive result from the remainder is incredibly unnatural. You can get this behavior through Python's definition trivially using `a % abs(b)`, making rem_euclid less flexible as well.
The reason it's incredibly unnatural is not obvious when looking at the remainder in isolation. But the remainder is always one half of a pair: remainder and quotient. The quotient associated with rem_euclid is batshit insane.
The quotient associated with Python's modulo definition is simply floor(a/b).
Note that I'm wording it very strongly when I say it is wrong. It follows its spec faithfully and isn't 'bugged', its spec is just poorly and unnaturally chosen.
> In other words, the result is self / rhs rounded to the integer q such that self >= q * rhs. If self > 0, this is equal to round towards zero (the default in Rust); if self < 0, this is equal to round towards +/- infinity.
Python gets it right. Division is simply flooring division, and modulo is defined to satisfy n = remainder + quotient * divisor. That immediately gets you all the nice behavior such as (-1) % 10 = 9, and 1 % -10 = -9.