From 0589cace8c943d40a60b7356d8c772baf2879cee Mon Sep 17 00:00:00 2001 From: Christopher Swenson Date: Mon, 10 Jan 2022 15:31:11 -0800 Subject: [PATCH] Simplify BigNum::bit_length() with log2() Thank you to @scottmcm for suggesting the handy `log2()` function. --- library/core/src/num/bignum.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs index 65c1753895e..98d8a8a1d74 100644 --- a/library/core/src/num/bignum.rs +++ b/library/core/src/num/bignum.rs @@ -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.