Simplify BigNum::bit_length() with log2()

Thank you to @scottmcm for suggesting the handy `log2()` function.
This commit is contained in:
Christopher Swenson 2022-01-10 15:31:11 -08:00
parent 424f38f211
commit 0589cace8c
1 changed files with 8 additions and 10 deletions

View File

@ -158,17 +158,15 @@ macro_rules! define_bignum {
/// Returns the number of bits necessary to represent this value. Note that zero
/// is considered to need 0 bits.
pub fn bit_length(&self) -> usize {
// Skip over the most significant digits which are zero.
let digits = self.digits();
let zeros = digits.iter().rev().take_while(|&&x| x == 0).count();
let end = digits.len() - zeros;
if end == 0 {
// There are no non-zero digits, i.e., the number is zero.
return 0;
}
let digitbits = <$ty>::BITS as usize;
let end_leading_zeros = digits[end - 1].leading_zeros() as usize;
end * digitbits - end_leading_zeros
let digits = self.digits();
// Find the most significant non-zero digit.
let msd = digits.iter().rposition(|&x| x != 0);
match msd {
Some(msd) => msd * digitbits + digits[msd].log2() as usize + 1,
// There are no non-zero digits, i.e., the number is zero.
_ => 0,
}
}
/// Adds `other` to itself and returns its own mutable reference.