1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! Bit-level trailing zero count for [`U256`].
use super::U256;
impl U256 {
/// Returns the number of trailing zero bits in the 256-bit value.
///
/// Scans from the least significant limb (`w3`) upward. Returns 256
/// for zero, 0 for any odd value, and the position of the lowest set
/// bit in general.
///
/// # Examples
///
/// ```
/// use cnfy_uint::u256::U256;
///
/// assert_eq!(U256::ZERO.trailing_zeros(), 256);
/// assert_eq!(U256::ONE.trailing_zeros(), 0);
/// assert_eq!(U256::from_be_limbs([0, 0, 0, 8]).trailing_zeros(), 3);
/// ```
#[inline]
pub const fn trailing_zeros(&self) -> u32 {
if self.0[0] != 0 {
self.0[0].trailing_zeros()
} else if self.0[1] != 0 {
64 + self.0[1].trailing_zeros()
} else if self.0[2] != 0 {
128 + self.0[2].trailing_zeros()
} else if self.0[3] != 0 {
192 + self.0[3].trailing_zeros()
} else {
256
}
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
/// Zero has 256 trailing zeros.
#[test]
fn zero() {
assert_eq!(U256::ZERO.trailing_zeros(), 256);
}
/// One has 0 trailing zeros.
#[test]
fn one() {
assert_eq!(U256::ONE.trailing_zeros(), 0);
}
/// MAX has 0 trailing zeros (all bits set).
#[test]
fn max() {
assert_eq!(U256::MAX.trailing_zeros(), 0);
}
/// Powers of two have trailing_zeros = exponent.
#[test]
fn powers_of_two() {
assert_eq!(U256::from_be_limbs([0, 0, 0, 2]).trailing_zeros(), 1);
assert_eq!(U256::from_be_limbs([0, 0, 0, 8]).trailing_zeros(), 3);
assert_eq!(U256::from_be_limbs([0, 0, 0, 0x100]).trailing_zeros(), 8);
assert_eq!(U256::from_be_limbs([0, 0, 1, 0]).trailing_zeros(), 64);
assert_eq!(U256::from_be_limbs([0, 1, 0, 0]).trailing_zeros(), 128);
assert_eq!(U256::from_be_limbs([1, 0, 0, 0]).trailing_zeros(), 192);
}
/// MSB-only value has 255 trailing zeros.
#[test]
fn msb_only() {
assert_eq!(
U256::from_be_limbs([0x8000000000000000, 0, 0, 0]).trailing_zeros(),
255,
);
}
/// Odd values always have 0 trailing zeros.
#[test]
fn odd_values() {
assert_eq!(U256::from_be_limbs([0, 0, 0, 3]).trailing_zeros(), 0);
assert_eq!(U256::from_be_limbs([0xFF, 0, 0, 1]).trailing_zeros(), 0);
}
/// Even values in higher limbs.
#[test]
fn higher_limb_trailing() {
// Only w2 set, at bit 64
assert_eq!(U256::from_be_limbs([0, 0, 1, 0]).trailing_zeros(), 64);
// w2 = 0x10 → trailing = 64 + 4 = 68
assert_eq!(U256::from_be_limbs([0, 0, 0x10, 0]).trailing_zeros(), 68);
}
}