Skip to content

Commit

Permalink
Add edge-case examples to {count,leading,trailing}_{ones,zeros} met…
Browse files Browse the repository at this point in the history
…hods

Some architectures (i386) do not define a "count leading zeros" instruction,
they define a "find first set bit" instruction (`bsf`) whose result is undefined
when given zero (ie none of the bits are set). Of this family of bitwise
operations, I always forget which of these things is potentially undefined for
zero, and I'm also not 100% sure that Rust provides a hard guarantee for the
results of these methods when given zero. So I figured there are others who have
these same uncertainties, and it would be good to resolve them and answer the
question via extending these doc examples/tests.

See https://en.wikipedia.org/wiki/Find_first_set#Hardware_support for more info
on i386 and `bsf` on zero.
  • Loading branch information
fitzgen committed Jul 2, 2024
1 parent c5ab1f0 commit 538fe81
Showing 1 changed file with 35 additions and 6 deletions.
41 changes: 35 additions & 6 deletions core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,13 @@ macro_rules! uint_impl {
///
/// ```
#[doc = concat!("let n = 0b01001100", stringify!($SelfT), ";")]
///
/// assert_eq!(n.count_ones(), 3);
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
#[doc = concat!("assert_eq!(max.count_ones(), ", stringify!($BITS), ");")]
///
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
/// assert_eq!(zero.count_ones(), 0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_math", since = "1.32.0")]
Expand All @@ -86,7 +91,11 @@ macro_rules! uint_impl {
/// Basic usage:
///
/// ```
#[doc = concat!("assert_eq!(", stringify!($SelfT), "::MAX.count_zeros(), 0);")]
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
#[doc = concat!("assert_eq!(zero.count_zeros(), ", stringify!($BITS), ");")]
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
/// assert_eq!(max.count_zeros(), 0);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_math", since = "1.32.0")]
Expand All @@ -108,8 +117,13 @@ macro_rules! uint_impl {
///
/// ```
#[doc = concat!("let n = ", stringify!($SelfT), "::MAX >> 2;")]
///
/// assert_eq!(n.leading_zeros(), 2);
///
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
#[doc = concat!("assert_eq!(zero.leading_zeros(), ", stringify!($BITS), ");")]
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
/// assert_eq!(max.leading_zeros(), 0);
/// ```
#[doc = concat!("[`ilog2`]: ", stringify!($SelfT), "::ilog2")]
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -130,8 +144,13 @@ macro_rules! uint_impl {
///
/// ```
#[doc = concat!("let n = 0b0101000", stringify!($SelfT), ";")]
///
/// assert_eq!(n.trailing_zeros(), 3);
///
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
#[doc = concat!("assert_eq!(zero.trailing_zeros(), ", stringify!($BITS), ");")]
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
#[doc = concat!("assert_eq!(max.trailing_zeros(), 0);")]
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_math", since = "1.32.0")]
Expand All @@ -150,8 +169,13 @@ macro_rules! uint_impl {
///
/// ```
#[doc = concat!("let n = !(", stringify!($SelfT), "::MAX >> 2);")]
///
/// assert_eq!(n.leading_ones(), 2);
///
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
/// assert_eq!(zero.leading_ones(), 0);
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
#[doc = concat!("assert_eq!(max.leading_ones(), ", stringify!($BITS), ");")]
/// ```
#[stable(feature = "leading_trailing_ones", since = "1.46.0")]
#[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
Expand All @@ -171,8 +195,13 @@ macro_rules! uint_impl {
///
/// ```
#[doc = concat!("let n = 0b1010111", stringify!($SelfT), ";")]
///
/// assert_eq!(n.trailing_ones(), 3);
///
#[doc = concat!("let zero = 0", stringify!($SelfT), ";")]
/// assert_eq!(zero.trailing_ones(), 0);
///
#[doc = concat!("let max = ", stringify!($SelfT),"::MAX;")]
#[doc = concat!("assert_eq!(max.trailing_ones(), ", stringify!($BITS), ");")]
/// ```
#[stable(feature = "leading_trailing_ones", since = "1.46.0")]
#[rustc_const_stable(feature = "leading_trailing_ones", since = "1.46.0")]
Expand Down

0 comments on commit 538fe81

Please sign in to comment.