Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* [Reverse Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/reverse_bits.rs)
* [Sum of Two Integers](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/sum_of_two_integers.rs)
* [Swap Odd and Even Bits](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/swap_odd_even_bits.rs)
* [Trailing Zeros](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/binary_count_trailing_zeros.rs)
* [Two's Complement](https://github.com/TheAlgorithms/Rust/blob/master/src/bit_manipulation/twos_complement.rs)
* Ciphers
* [AES](https://github.com/TheAlgorithms/Rust/blob/master/src/ciphers/aes.rs)
Expand Down
119 changes: 119 additions & 0 deletions src/bit_manipulation/binary_count_trailing_zeros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/// Counts the number of trailing zeros in the binary representation of a number
///
/// # Arguments
///
/// * `num` - The input number
///
/// # Returns
///
/// The number of trailing zeros in the binary representation
///
/// # Examples
///
/// ```
/// use the_algorithms_rust::bit_manipulation::binary_count_trailing_zeros;
///
/// assert_eq!(binary_count_trailing_zeros(25), 0);
/// assert_eq!(binary_count_trailing_zeros(36), 2);
/// assert_eq!(binary_count_trailing_zeros(16), 4);
/// assert_eq!(binary_count_trailing_zeros(58), 1);
/// ```
pub fn binary_count_trailing_zeros(num: u64) -> u32 {
if num == 0 {
return 0;
}
num.trailing_zeros()
}

/// Alternative implementation using bit manipulation
///
/// Uses the bit manipulation trick: log2(num & -num)
///
/// # Examples
///
/// ```
/// // This function uses bit manipulation: log2(num & -num)
/// // where num & -num isolates the rightmost set bit
/// # fn binary_count_trailing_zeros_bitwise(num: u64) -> u32 {
/// # if num == 0 { return 0; }
/// # let rightmost_set_bit = num & (num.wrapping_neg());
/// # 63 - rightmost_set_bit.leading_zeros()
/// # }
/// assert_eq!(binary_count_trailing_zeros_bitwise(25), 0);
/// assert_eq!(binary_count_trailing_zeros_bitwise(36), 2);
/// assert_eq!(binary_count_trailing_zeros_bitwise(16), 4);
/// ```
#[allow(dead_code)]
pub fn binary_count_trailing_zeros_bitwise(num: u64) -> u32 {
if num == 0 {
return 0;
}

let rightmost_set_bit = num & (num.wrapping_neg());
63 - rightmost_set_bit.leading_zeros()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_basic_cases() {
assert_eq!(binary_count_trailing_zeros(25), 0);
assert_eq!(binary_count_trailing_zeros(36), 2);
assert_eq!(binary_count_trailing_zeros(16), 4);
assert_eq!(binary_count_trailing_zeros(58), 1);
assert_eq!(binary_count_trailing_zeros(4294967296), 32);
}

#[test]
fn test_zero() {
assert_eq!(binary_count_trailing_zeros(0), 0);
}

#[test]
fn test_powers_of_two() {
assert_eq!(binary_count_trailing_zeros(1), 0);
assert_eq!(binary_count_trailing_zeros(2), 1);
assert_eq!(binary_count_trailing_zeros(4), 2);
assert_eq!(binary_count_trailing_zeros(8), 3);
assert_eq!(binary_count_trailing_zeros(1024), 10);
}

#[test]
fn test_bitwise_vs_builtin() {
// Test that bitwise implementation matches built-in trailing_zeros()
let test_cases = vec![
0,
1,
2,
3,
4,
5,
6,
7,
8,
16,
25,
36,
58,
64,
100,
128,
256,
512,
1024,
4294967296,
u64::MAX - 1,
u64::MAX,
];

for num in test_cases {
assert_eq!(
binary_count_trailing_zeros(num),
binary_count_trailing_zeros_bitwise(num),
"Mismatch for input: {num}"
);
}
}
}
2 changes: 2 additions & 0 deletions src/bit_manipulation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod binary_coded_decimal;
mod binary_count_trailing_zeros;
mod counting_bits;
mod find_previous_power_of_two;
mod highest_set_bit;
Expand All @@ -10,6 +11,7 @@ mod swap_odd_even_bits;
mod twos_complement;

pub use self::binary_coded_decimal::binary_coded_decimal;
pub use self::binary_count_trailing_zeros::binary_count_trailing_zeros;
pub use self::counting_bits::count_set_bits;
pub use self::find_previous_power_of_two::find_previous_power_of_two;
pub use self::highest_set_bit::find_highest_set_bit;
Expand Down