-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Improve documentation of next_power_of_two #40706
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
Changes from 2 commits
f7c641b
04e9c20
f7bd370
8f9caff
67684a3
ed24829
93219a2
18fadb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2328,7 +2328,7 @@ macro_rules! uint_impl { | |
} | ||
|
||
/// Returns the smallest power of two greater than or equal to `self`. | ||
/// Unspecified behavior on overflow. | ||
/// More details about overflow behavior can be found in [RFC 560]. | ||
/// | ||
/// # Examples | ||
/// | ||
|
@@ -2338,12 +2338,18 @@ macro_rules! uint_impl { | |
/// assert_eq!(2u8.next_power_of_two(), 2); | ||
/// assert_eq!(3u8.next_power_of_two(), 4); | ||
/// ``` | ||
/// | ||
/// [RFC 560]: https://github.com/rust-lang/rfcs/blob/master/text/0560-integer-overflow.md | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
#[inline] | ||
pub fn next_power_of_two(self) -> Self { | ||
let bits = size_of::<Self>() * 8; | ||
let one: Self = 1; | ||
one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits) | ||
if self == 0 { | ||
1 | ||
} else { | ||
one << (bits - self.wrapping_sub(one).leading_zeros() as usize) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically, you can replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stjepang Thanks for the suggestion. |
||
} | ||
} | ||
|
||
/// Returns the smallest power of two greater than or equal to `n`. If | ||
|
@@ -2361,7 +2367,9 @@ macro_rules! uint_impl { | |
/// ``` | ||
#[stable(feature = "rust1", since = "1.0.0")] | ||
pub fn checked_next_power_of_two(self) -> Option<Self> { | ||
let npot = self.next_power_of_two(); | ||
let bits = size_of::<Self>() * 8; | ||
let one: Self = 1; | ||
let npot = one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this going to panic if Also, I'd personally find the following slightly easier to understand (but I don't mind the current code either): let shift = bits - self.wrapping_sub(one).leading_zeros() as usize;
if shift < bits {
Some(one << shift)
} else {
None
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By the way, do we have tests for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are tests for |
||
if npot >= self { | ||
Some(npot) | ||
} else { | ||
|
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'd leave the old sentence and put the new one after it.
Reading through a long RFC just to figure out what happens on overflow may be tedious. :)
It should be clear that on overflow something unspecified will happen, but if the reader wants to find out more - there's a link to the RFC.
Uh oh!
There was an error while loading. Please reload this page.
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.
Is it actually true that the behavior is unspecified? For normal arithmetic at least, the RFC used to state that behavior was unspecified, but soon afterwards it was specified as "panic in debug, wrapping in release" (slightly simplified).
Edit: The RFC doesn't actually mention
next_power_of_two
specifically. I suppose the behavior referred to is just the general overflow behavior, then?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.
By the way I agree that we should not just link to an RFC (which is not written for end users, and very much a historic document). But the old sentence is plainly wrong AFAIK.
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 like it doesn't panic even in debug mode: https://is.gd/pmGoPY
Although by "unspecified behavior" I take it could possibly panic, but doesn't have to.
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.
Hm, this doesn't match what was discussed in #18604, specifically #18604 (comment) indicates it should panic in debug mode.
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 agree that linking to RFC might not be a good idea.
From what I understand about overflow behavior (correct me if I'm wrong)
#[allow(overflowing_literals)]
https://is.gd/M6Oxnf-Z force-overflow-checks=off
flag.I could not find any page in doc which documents behavior on overflow so I linked to RFC. Let me know if there is a page which should be linked.
Or we could just remove this section because overflow behavior across the whole program should now be consistent