I recently encountered a situation where I wanted to divide two integers and assert that the result was not rounded — that is, a == b / c <=> a * c == b.
I saw that there's an intrinsic called exact_div which achieves this but I would prefer not to rely on it. Unfortunately, there's no stabilized version of it.
I propose adding some new integer methods:
exact_div_unchecked(): equivalent to the current exact_div — causes UB if the operands are invalid (rounding has occurred, or rhs == 0, or lhs == MIN && rhs == -1).
exact_div_checked(): returns None if the operands are invalid.
No thoughts, just letting you know that the mechanism to suggest a new API for the libs team is to file an ACP at GitHub · Where software is built.
I would include the full signature of the functions in that proposal, not just the name.
Also, note that the existing exact_div intrinsic corresponds to your exact_div_unchecked. I don't know if there's a nice an efficient way to implement the checked version.
I saw a decent number of comments on that, it sounded like noone was sure how it would be efficiently implemented.
In my experience the ACPs with a fast turnaround are the ones where the ACP author also implements the feature (this is what I tend to do when I write ACPs)
I think I'd prefer a div_mod or div_rem that returns (a / b, a % b). Let the user do with the second element of the pair what they will. I think the num crate has this but it may be worth including in the std lib.
Yeah as I mentioned in the issue, div_rem would work nicely for this:
if let (quotient, 0) = whatever.div_rem(PAGE_SIZE) {
// divides evenly
} else {
// there was a remainder
}
// OR for the "unchecked" version
let (quotient, 0) = whatever.div_rem(PAGE_SIZE) else {
unreachable_unchecked()
};
It took me multiple times of reading through this to understand why you are talking about a trait. I'd suggest simplifying the description -- we all know one can write extension traits, but that has little to do with the actual API here.
Also, that's not exact_div as it is safe which exact_div is not.
So I'd suggest to update the ACP or file an updated ACP. Then we can try to ping libs-api to get it nominated for one of their next meetings. (I don't know if they have any systematic approach to their backlog.)
I highly doubt that "unchecked" version will optimize the same way as exact_div which compiles to an LLVM intrinsic.
I was talking about the trait only in the "motivating examples or use cases" section. The proposal itself (the "solution sketch" section) is extremely simple and adds only two methods (I guess we also could add unsafe unchecked_norem_div as a wrapper around exact_div), I don't know how to make it simpler than that. I also had the open PR for those who are more interested in concrete implementation.
Yeah I realized that eventually. But it's entirely unnecessary to equip the motivating example with a trait here... it's just confusing and distracting from the core point.
I mentioned the trait because it was an alternative which we use today in practice and I vaguely remember that some argued that we do not need these methods because people can define such extension traits for a niche (in their opinion) use case.
UPD: I have removed the trait part and renamed the suggested methods to ((un)checked_)exact_div.
I was just giving feedback on how you could make your proposal more crisp in my view, and communicate your intent more clearly. Do with that feedback whatever you want .
EDIT: Yeah I think that's better. It's still not a clear case for why that has to be in std, but that would require more independent use-cases and I know that can be hard to get by. The unsafe version has a clear motivation for being in std as that's the only way the compiler is going to be able to make good use of it.
I was curious, and yup, you're right. assumeing that the remainder is zero doesn't get the exact flag on the division: https://rust.godbolt.org/z/o9YhvjfM1.