let digits = self.digits();
let zeros = digits.iter().rev().take_while(|&&x| x == 0).count();
let end = digits.len() - zeros;
- let nonzero = &digits[..end];
-
- if nonzero.is_empty() {
+ if end == 0 {
// There are no non-zero digits, i.e., the number is zero.
return 0;
}
- // This could be optimized with leading_zeros() and bit shifts, but that's
- // probably not worth the hassle.
let digitbits = <$ty>::BITS as usize;
- let mut i = nonzero.len() * digitbits - 1;
- while self.get_bit(i) == 0 {
- i -= 1;
- }
- i + 1
+ 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.
use core::num::bignum::tests::Big8x3 as Big;
+use core::num::bignum::Big32x40;
#[test]
#[should_panic]
#[test]
fn test_bit_length() {
+ for i in 0..8 * 3 {
+ // 010000...000
+ assert_eq!(Big::from_small(1).mul_pow2(i).bit_length(), i + 1);
+ }
+ for i in 1..8 * 3 - 1 {
+ // 010000...001
+ assert_eq!(Big::from_small(1).mul_pow2(i).add(&Big::from_small(1)).bit_length(), i + 1);
+ // 110000...000
+ assert_eq!(Big::from_small(3).mul_pow2(i).bit_length(), i + 2);
+ }
assert_eq!(Big::from_small(0).bit_length(), 0);
assert_eq!(Big::from_small(1).bit_length(), 1);
assert_eq!(Big::from_small(5).bit_length(), 3);
assert_eq!(Big::from_u64(0xffffff).bit_length(), 24);
}
+#[test]
+fn test_bit_length_32x40() {
+ for i in 0..32 * 40 {
+ // 010000...000
+ assert_eq!(Big32x40::from_small(1).mul_pow2(i).bit_length(), i + 1);
+ }
+ for i in 1..32 * 40 - 1 {
+ // 010000...001
+ assert_eq!(
+ Big32x40::from_small(1).mul_pow2(i).add(&Big32x40::from_small(1)).bit_length(),
+ i + 1
+ );
+ // 110000...000
+ assert_eq!(Big32x40::from_small(3).mul_pow2(i).bit_length(), i + 2);
+ }
+ assert_eq!(Big32x40::from_small(0).bit_length(), 0);
+ assert_eq!(Big32x40::from_small(1).bit_length(), 1);
+ assert_eq!(Big32x40::from_small(5).bit_length(), 3);
+ assert_eq!(Big32x40::from_small(0x18).bit_length(), 5);
+ assert_eq!(Big32x40::from_u64(0x4073).bit_length(), 15);
+ assert_eq!(Big32x40::from_u64(0xffffff).bit_length(), 24);
+ assert_eq!(Big32x40::from_u64(0xffffffffffffffff).bit_length(), 64);
+}
+
#[test]
fn test_ord() {
assert!(Big::from_u64(0) < Big::from_u64(0xffffff));