11/// Counts the number of trailing zeros in the binary representation of a number
22///
3- /// Takes an unsigned integer and returns the count of trailing zeros (consecutive
4- /// zeros from the least significant bit) in its binary representation.
5- ///
63/// # Arguments
74///
8- /// * `num` - The input number (unsigned integer)
5+ /// * `num` - The input number
96///
107/// # Returns
118///
1613/// ```
1714/// use the_algorithms_rust::bit_manipulation::binary_count_trailing_zeros;
1815///
19- /// assert_eq!(binary_count_trailing_zeros(25), 0); // 11001 -> 0 trailing zeros
20- /// assert_eq!(binary_count_trailing_zeros(36), 2); // 100100 -> 2 trailing zeros
21- /// assert_eq!(binary_count_trailing_zeros(16), 4); // 10000 -> 4 trailing zeros
22- /// assert_eq!(binary_count_trailing_zeros(58), 1); // 111010 -> 1 trailing zero
23- /// assert_eq!(binary_count_trailing_zeros(4294967296), 32);
24- /// assert_eq!(binary_count_trailing_zeros(0), 0);
16+ /// assert_eq!(binary_count_trailing_zeros(25), 0);
17+ /// assert_eq!(binary_count_trailing_zeros(36), 2);
18+ /// assert_eq!(binary_count_trailing_zeros(16), 4);
19+ /// assert_eq!(binary_count_trailing_zeros(58), 1);
2520/// ```
26- ///
27- /// # Algorithm Explanation
28- ///
29- /// This function uses Rust's built-in `trailing_zeros()` method, which efficiently
30- /// counts trailing zeros using CPU instructions. The method works by:
31- /// 1. Examining the binary representation from right to left
32- /// 2. Counting consecutive zeros until hitting the first 1 bit
33- /// 3. Returning the count
34- ///
35- /// Alternative implementation using bit manipulation:
36- /// The count can also be computed using: `log2(num & -num)`
37- /// - `num & -num` isolates the rightmost set bit
38- /// - Taking log2 gives the position of that bit (= trailing zeros count)
3921pub fn binary_count_trailing_zeros ( num : u64 ) -> u32 {
40- // Handle zero case explicitly to match Python behavior
4122 if num == 0 {
4223 return 0 ;
4324 }
44-
45- // Rust's built-in method for counting trailing zeros
46- // Note: trailing_zeros() on 0 returns the bit width (64 for u64)
47- // but we handle zero separately above
4825 num. trailing_zeros ( )
4926}
5027
51- /// Alternative implementation using bit manipulation and logarithm
28+ /// Alternative implementation using bit manipulation
5229///
53- /// This matches the Python implementation more closely by using the
54- /// bit manipulation trick: log2(num & -num)
30+ /// Uses the bit manipulation trick: log2(num & -num)
5531///
5632/// # Examples
5733///
5834/// ```
59- /// # use the_algorithms_rust::bit_manipulation::binary_count_trailing_zeros;
60- /// // Note: This is an internal alternative implementation
61- /// // For actual use, call binary_count_trailing_zeros() instead
62- /// assert_eq!(binary_count_trailing_zeros(25), 0);
63- /// assert_eq!(binary_count_trailing_zeros(36), 2);
64- /// assert_eq!(binary_count_trailing_zeros(16), 4);
35+ /// # use the_algorithms_rust::bit_manipulation::binary_count_trailing_zeros_bitwise;
36+ /// assert_eq!(binary_count_trailing_zeros_bitwise(25), 0);
37+ /// assert_eq!(binary_count_trailing_zeros_bitwise(36), 2);
6538/// ```
66- #[ allow( dead_code) ]
6739pub fn binary_count_trailing_zeros_bitwise ( num : u64 ) -> u32 {
6840 if num == 0 {
6941 return 0 ;
7042 }
71-
72- // The bit manipulation trick: num & -num isolates the rightmost set bit
73- // Taking log2 gives us the position (number of trailing zeros)
43+
7444 let rightmost_set_bit = num & ( num. wrapping_neg ( ) ) ;
75-
76- // Calculate log2 using leading zeros
77- // log2(x) = 63 - leading_zeros(x) for u64
7845 63 - rightmost_set_bit. leading_zeros ( )
7946}
8047
@@ -84,14 +51,10 @@ mod tests {
8451
8552 #[ test]
8653 fn test_basic_cases ( ) {
87- assert_eq ! ( binary_count_trailing_zeros( 25 ) , 0 ) ; // 11001
88- assert_eq ! ( binary_count_trailing_zeros( 36 ) , 2 ) ; // 100100
89- assert_eq ! ( binary_count_trailing_zeros( 16 ) , 4 ) ; // 10000
90- assert_eq ! ( binary_count_trailing_zeros( 58 ) , 1 ) ; // 111010
91- }
92-
93- #[ test]
94- fn test_large_number ( ) {
54+ assert_eq ! ( binary_count_trailing_zeros( 25 ) , 0 ) ;
55+ assert_eq ! ( binary_count_trailing_zeros( 36 ) , 2 ) ;
56+ assert_eq ! ( binary_count_trailing_zeros( 16 ) , 4 ) ;
57+ assert_eq ! ( binary_count_trailing_zeros( 58 ) , 1 ) ;
9558 assert_eq ! ( binary_count_trailing_zeros( 4294967296 ) , 32 ) ;
9659 }
9760
@@ -102,61 +65,23 @@ mod tests {
10265
10366 #[ test]
10467 fn test_powers_of_two ( ) {
105- // Powers of 2 have trailing zeros equal to their exponent
106- assert_eq ! ( binary_count_trailing_zeros( 1 ) , 0 ) ; // 2^0
107- assert_eq ! ( binary_count_trailing_zeros( 2 ) , 1 ) ; // 2^1
108- assert_eq ! ( binary_count_trailing_zeros( 4 ) , 2 ) ; // 2^2
109- assert_eq ! ( binary_count_trailing_zeros( 8 ) , 3 ) ; // 2^3
110- assert_eq ! ( binary_count_trailing_zeros( 1024 ) , 10 ) ; // 2^10
111- }
112-
113- #[ test]
114- fn test_odd_numbers ( ) {
115- // Odd numbers always have 0 trailing zeros
11668 assert_eq ! ( binary_count_trailing_zeros( 1 ) , 0 ) ;
117- assert_eq ! ( binary_count_trailing_zeros( 3 ) , 0 ) ;
118- assert_eq ! ( binary_count_trailing_zeros( 5 ) , 0 ) ;
119- assert_eq ! ( binary_count_trailing_zeros( 7 ) , 0 ) ;
120- assert_eq ! ( binary_count_trailing_zeros( 99 ) , 0 ) ;
121- }
122-
123- #[ test]
124- fn test_even_numbers ( ) {
125- assert_eq ! ( binary_count_trailing_zeros( 2 ) , 1 ) ; // 10
126- assert_eq ! ( binary_count_trailing_zeros( 4 ) , 2 ) ; // 100
127- assert_eq ! ( binary_count_trailing_zeros( 6 ) , 1 ) ; // 110
128- assert_eq ! ( binary_count_trailing_zeros( 8 ) , 3 ) ; // 1000
129- assert_eq ! ( binary_count_trailing_zeros( 12 ) , 2 ) ; // 1100
69+ assert_eq ! ( binary_count_trailing_zeros( 2 ) , 1 ) ;
70+ assert_eq ! ( binary_count_trailing_zeros( 4 ) , 2 ) ;
71+ assert_eq ! ( binary_count_trailing_zeros( 8 ) , 3 ) ;
72+ assert_eq ! ( binary_count_trailing_zeros( 1024 ) , 10 ) ;
13073 }
13174
13275 #[ test]
13376 fn test_bitwise_implementation ( ) {
134- // Test that both implementations give the same results
13577 let test_cases = vec ! [ 0 , 1 , 2 , 4 , 8 , 16 , 25 , 36 , 58 , 1024 , 4294967296 ] ;
136-
78+
13779 for num in test_cases {
13880 assert_eq ! (
13981 binary_count_trailing_zeros( num) ,
14082 binary_count_trailing_zeros_bitwise( num) ,
141- "Mismatch for input: {}" ,
142- num
83+ "Mismatch for input: {num}"
14384 ) ;
14485 }
14586 }
146-
147- #[ test]
148- fn test_max_value ( ) {
149- // Test with maximum u64 value
150- let max_u64 = u64:: MAX ;
151- assert_eq ! ( binary_count_trailing_zeros( max_u64) , 0 ) ; // All 1s, no trailing zeros
152- }
153-
154- #[ test]
155- fn test_patterns ( ) {
156- // Test specific binary patterns
157- assert_eq ! ( binary_count_trailing_zeros( 0b1000 ) , 3 ) ;
158- assert_eq ! ( binary_count_trailing_zeros( 0b10000 ) , 4 ) ;
159- assert_eq ! ( binary_count_trailing_zeros( 0b100000 ) , 5 ) ;
160- assert_eq ! ( binary_count_trailing_zeros( 0b1111000 ) , 3 ) ;
161- }
16287}
0 commit comments