Create a number with n leading zeros

Hi, I'm trying to create a usize that has n leading zeros. I have tried all of the following:

    let (first_idx, _) = usize::MAX.overflowing_shr(leading_zeros);
    let first_idx = usize::MAX.wrapping_shr(leading_zeros);
    let first_idx = usize::MAX.rotate_right(leading_zeros);

however in all cases I get the same result of 18446744073709551615.

If I try this:

let first_idx = usize::MAX >> leading_zeros;

I get a runtime overflow error.

I don't get why all three methods exist if they seem to do the same thing? They all rotate bits off the right and onto the left, but I need a way to just get rid of them.

You may be looking at the results wrong. For me, the first two versions do produce leading zeroes:

fn main() {
    let leading_zeros = 7;
    let (first_idx, _) = usize::MAX.overflowing_shr(leading_zeros);
    println!("{first_idx:0>64b}");
    let first_idx = usize::MAX.wrapping_shr(leading_zeros);
    println!("{first_idx:0>64b}");
    let first_idx = usize::MAX.rotate_right(leading_zeros);
    println!("{first_idx:0>64b}");
}
0000000111111111111111111111111111111111111111111111111111111111
0000000111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111

Rust Playground

2 Likes

I don't get the same result as you do:

fn main() {
    let leading_zeros = 63;
    
    let (first_idx, _) = usize::MAX.overflowing_shr(leading_zeros);
    
    println!("{first_idx}");
    
    let first_idx = usize::MAX.wrapping_shr(leading_zeros);
    
    println!("{first_idx}");
    
    let first_idx = usize::MAX.rotate_right(leading_zeros);
    
    println!("{first_idx}");
}

prints:

1
1
18446744073709551615

Playground.

1 Like

Looks like n = 64 works for none of them, though :slight_smile:

Shifting instructions typically expect n < 64 (on a 64-bit value), and will often truncate the amunt shifted by in a mod 64 (on a 64-bit value) fashion.

On a first look, I don’t see any existing methods that handle n >= 64 cases by producing an all-zeroes result. In case this is desired, you may need to simply introduce an if condition that returns 0 manually in those cases.

2 Likes

Yep, I think the issue is that I'm running this in a loop so I'm always testing with leading_zeros = 64 first and getting a panic. Still frustrating that this method works for all numbers except 0 : /

Edit: Also just realized that it's much easier, and probably faster, to just do a (1 << leading_zeros) - 1. Twas being a dunce

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.