use super::U512;
impl U512 {
#[inline]
pub const fn leading_zeros(&self) -> u32 {
if self.0[7] != 0 {
self.0[7].leading_zeros()
} else if self.0[6] != 0 {
64 + self.0[6].leading_zeros()
} else if self.0[5] != 0 {
128 + self.0[5].leading_zeros()
} else if self.0[4] != 0 {
192 + self.0[4].leading_zeros()
} else if self.0[3] != 0 {
256 + self.0[3].leading_zeros()
} else if self.0[2] != 0 {
320 + self.0[2].leading_zeros()
} else if self.0[1] != 0 {
384 + self.0[1].leading_zeros()
} else if self.0[0] != 0 {
448 + self.0[0].leading_zeros()
} else {
512
}
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
#[test]
fn zero() {
assert_eq!(U512::ZERO.leading_zeros(), 512);
}
#[test]
fn one() {
assert_eq!(U512::ONE.leading_zeros(), 511);
}
#[test]
fn max() {
assert_eq!(U512::MAX.leading_zeros(), 0);
}
#[test]
fn consistent_with_bit_len() {
let cases = [
U512::ONE,
U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, 0xFF]),
U512::from_be_limbs([0, 0, 0, 0, 0, 0, 1, 0]),
U512::from_be_limbs([0, 0, 0, 0, 1, 0, 0, 0]),
U512::from_be_limbs([1, 0, 0, 0, 0, 0, 0, 0]),
U512::MAX,
];
for v in &cases {
assert_eq!(v.leading_zeros() + v.bit_len(), 512);
}
}
#[test]
fn powers_of_two() {
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, 1]).leading_zeros(), 511);
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 0, 1, 0]).leading_zeros(), 447);
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 1, 0, 0]).leading_zeros(), 383);
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 1, 0, 0, 0]).leading_zeros(), 319);
assert_eq!(U512::from_be_limbs([0, 0, 0, 1, 0, 0, 0, 0]).leading_zeros(), 255);
assert_eq!(U512::from_be_limbs([0, 0, 1, 0, 0, 0, 0, 0]).leading_zeros(), 191);
assert_eq!(U512::from_be_limbs([0, 1, 0, 0, 0, 0, 0, 0]).leading_zeros(), 127);
assert_eq!(U512::from_be_limbs([1, 0, 0, 0, 0, 0, 0, 0]).leading_zeros(), 63);
}
#[test]
fn limb_boundaries() {
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, u64::MAX]).leading_zeros(), 448);
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 0, u64::MAX, 0]).leading_zeros(), 384);
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, u64::MAX, 0, 0, 0]).leading_zeros(), 256);
assert_eq!(U512::from_be_limbs([u64::MAX, 0, 0, 0, 0, 0, 0, 0]).leading_zeros(), 0);
}
#[test]
fn byte_boundary() {
assert_eq!(U512::from_be_limbs([0, 0, 0, 0, 0, 0, 0, 0x80]).leading_zeros(), 504);
}
}