Skip to content

Commit c0259d9

Browse files
Update binary_count_trailing_zeros.rs
1 parent 4ff76c7 commit c0259d9

1 file changed

Lines changed: 21 additions & 96 deletions

File tree

Lines changed: 21 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
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
///
@@ -16,65 +13,35 @@
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)
3921
pub 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)]
6739
pub 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

Comments
 (0)