-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement RFC #2169 (Euclidean modulo). #49389
Conversation
Tracking issue: rust-lang#49048
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @KodrAus (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good! I've left a few very minor comments, but apart from that and fixing the tidy errors, I can't see any problems!
src/libcore/num/mod.rs
Outdated
@@ -1318,6 +1460,40 @@ $EndFeature, " | |||
} | |||
} | |||
|
|||
|
|||
doc_comment! { | |||
concat!("Calculates the modulo of Euclidean divsion `self.mod_euc(rhs)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I would call this "the remainder" or "the modulus", as "modulo" is the operation, rather than the result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing to "remainder" since "modulus" is another word for "divisor".
src/libcore/num/mod.rs
Outdated
|
||
|
||
doc_comment! { | ||
concat!("Calculates the modulo `self mod rhs` by Euclidean division. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here.
src/libcore/num/mod.rs
Outdated
doc_comment! { | ||
concat!("Calculates the quotient of Euclidean division of `self` by `rhs`. | ||
|
||
This computes the integer n such that `self = n * rhs + self.mod_euc(rhs)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: backticks around n
for consistency (and in f32
/f64
).
src/libcore/num/mod.rs
Outdated
#[unstable(feature = "euclidean_division", issue = "49048")] | ||
#[inline] | ||
pub fn wrapping_div_euc(self, rhs: Self) -> Self { | ||
self.div_euc(rhs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be the standard self / rhs
to avoid the extra branch (like with wrapping_mod_euc
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
I was just wondering whether the |
As far as I'm aware, the
Edit: just realised the floating-point methods are not in |
@varkor That makes sense. So I should move the float methods to libcore? Edit: Apparently, to move it there, I would have to add the |
I got a little confused before, sorry! I think it would be better to move the methods to |
Fair enough, I'll move it into libcore. But since |
Ah, I didn't spot that. In that case, let's just leave it in |
Ping from triage, @KodrAus ! Will you have time to review soon? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late review! This is looking good, thanks @fanzier. I've just left a few nitpicky comments about the docs. Once we're happy with those I think we can push this through.
src/libcore/num/mod.rs
Outdated
concat!("Wrapping Euclidean division. Computes `self.div_euc(rhs)`, | ||
wrapping around at the boundary of the type. | ||
|
||
The only case where such wrapping can occur is when one divides `MIN / -1` on a signed type (where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The wording here feels a little wonky. How about:
Wrapping will occur in MIN / -1
on a signed type (where MIN
is the negative minimal value for the type). This is equivalent to -MIN
, a positive value that is too large to represent in the type. In this case, this method returns MIN
itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I almost copy-pasted that documentation from wrapping_div
. Should I update the documentation there as well or should that be a separate PR?
src/libcore/num/mod.rs
Outdated
concat!("Wrapping Euclidean modulo. Computes `self.mod_euc(rhs)`, wrapping around at the | ||
boundary of the type. | ||
|
||
Such wrap-around never actually occurs mathematically; implementation artifacts make `x % y` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. How about:
Wrapping will occur in MIN % -1
on a signed type (where MIN
is the negative minimal value for the type). In this case, this method return 0.
src/libcore/num/mod.rs
Outdated
concat!("Calculates the quotient of Euclidean division `self.div_euc(rhs)`. | ||
|
||
Returns a tuple of the divisor along with a boolean indicating whether an arithmetic overflow would | ||
occur. If an overflow would occur then self is returned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should put self in backticks here.
📌 Commit ca4e458 has been approved by |
☀️ Test successful - status-appveyor, status-travis |
Is the compiler able to specialize to Euclidean modulus for powers of two? One of the reasons the Euclidean definition is the right one (unfortunately, Rust committed already to the weird C definition) is that It would be nice to know I can compute remainders modulo a power of two in all cases and be sure they will be reduced to a logical bit operation. |
Tracking issue: #49048