43 ms·
Can you clarify why is Rust's div_euclid and rem_euclid are incorrect? For reference, here's what Rust prints for this https://play.rust-lang.org/?version=stabl
by nextaccountic 4y ago
Can you clarify why is Rust's div_euclid and rem_euclid are incorrect? For reference, here's what Rust prints for this https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=a0ff242df33a7d411f803cd06cd04f40 https://play.rust-lang.org/?version=stable&mode=debug&editio...
fn main() {
dbg!(1_i32.rem_euclid(-10));
dbg!(-1_i32.rem_euclid(10));
}
[src/main.rs:2] 1_i32.rem_euclid(-10) = 1
[src/main.rs:3] -1_i32.rem_euclid(10) = -1
I found only this issue https://github.com/rust-lang/rust/issues/87970 https://github.com/rust-lang/rust/issues/87970 but has no details
Here's the discussion that lead to the implementation of those functions, from more recent to least recent,
* the tracking issue https://github.com/rust-lang/rust/issues/49048 https://github.com/rust-lang/rust/issues/49048
* the RFC https://github.com/rust-lang/rfcs/pull/2169 https://github.com/rust-lang/rfcs/pull/2169
* the internals discussion https://internals.rust-lang.org/t/mathematical-modulo-operator/5952 https://internals.rust-lang.org/t/mathematical-modulo-operat...
It's baffling that Rust got this wrong..
- LegionMammal978 4y agoThe 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.
- nextaccountic 4y agoOh, indeed. But, is the first one wrong then? But why should 1_i32.rem_euclid(-10) return -9 instead of 1?
- orlp 4y agoBecause 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.