]> git.lizzy.rs Git - rust.git/commitdiff
Simplify BigNum::bit_length() with log2()
authorChristopher Swenson <swenson@swenson.io>
Mon, 10 Jan 2022 23:31:11 +0000 (15:31 -0800)
committerChristopher Swenson <swenson@swenson.io>
Mon, 10 Jan 2022 23:31:11 +0000 (15:31 -0800)
Thank you to @scottmcm for suggesting the handy `log2()` function.

library/core/src/num/bignum.rs

index 65c1753895e7162928eaa7e449e001d33a975d14..98d8a8a1d74aebd822326df20390147d4e099d47 100644 (file)
@@ -158,17 +158,15 @@ pub fn is_zero(&self) -> bool {
             /// 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 digitbits = <$ty>::BITS as usize;
                 let digits = self.digits();
-                let zeros = digits.iter().rev().take_while(|&&x| x == 0).count();
-                let end = digits.len() - zeros;
-                if end == 0 {
+                // 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.
-                    return 0;
+                    _ => 0,
                 }
-                let digitbits = <$ty>::BITS as usize;
-                let end_leading_zeros = digits[end - 1].leading_zeros() as usize;
-                end * digitbits - end_leading_zeros
             }
 
             /// Adds `other` to itself and returns its own mutable reference.