diff --git a/src/bit_manipulation/counting_bits.rs b/src/bit_manipulation/counting_bits.rs index eabd529d140..9357ca3080c 100644 --- a/src/bit_manipulation/counting_bits.rs +++ b/src/bit_manipulation/counting_bits.rs @@ -1,11 +1,19 @@ -/* -The counting bits algorithm, also known as the "population count" or "Hamming weight," -calculates the number of set bits (1s) in the binary representation of an unsigned integer. -It uses a technique known as Brian Kernighan's algorithm, which efficiently clears the least -significant set bit in each iteration. -*/ - -pub fn count_set_bits(mut n: u32) -> u32 { +//! This module implements a function to count the number of set bits (1s) +//! in the binary representation of an unsigned integer. +//! It uses Brian Kernighan's algorithm, which efficiently clears the least significant +//! set bit in each iteration until all bits are cleared. +//! The algorithm runs in O(k), where k is the number of set bits. + +/// Counts the number of set bits in an unsigned integer. +/// +/// # Arguments +/// +/// * `n` - An unsigned 32-bit integer whose set bits will be counted. +/// +/// # Returns +/// +/// * `usize` - The number of set bits (1s) in the binary representation of the input number. +pub fn count_set_bits(mut n: usize) -> usize { // Initialize a variable to keep track of the count of set bits let mut count = 0; while n > 0 { @@ -24,23 +32,23 @@ pub fn count_set_bits(mut n: u32) -> u32 { mod tests { use super::*; - #[test] - fn test_count_set_bits_zero() { - assert_eq!(count_set_bits(0), 0); - } - - #[test] - fn test_count_set_bits_one() { - assert_eq!(count_set_bits(1), 1); + macro_rules! test_count_set_bits { + ($($name:ident: $test_case:expr,)*) => { + $( + #[test] + fn $name() { + let (input, expected) = $test_case; + assert_eq!(count_set_bits(input), expected); + } + )* + }; } - - #[test] - fn test_count_set_bits_power_of_two() { - assert_eq!(count_set_bits(16), 1); // 16 is 2^4, only one set bit - } - - #[test] - fn test_count_set_bits_all_set_bits() { - assert_eq!(count_set_bits(u32::MAX), 32); // Maximum value for u32, all set bits + test_count_set_bits! { + test_count_set_bits_zero: (0, 0), + test_count_set_bits_one: (1, 1), + test_count_set_bits_power_of_two: (16, 1), + test_count_set_bits_all_set_bits: (usize::MAX, std::mem::size_of::() * 8), + test_count_set_bits_alternating_bits: (0b10101010, 4), + test_count_set_bits_mixed_bits: (0b11011011, 6), } } diff --git a/src/bit_manipulation/highest_set_bit.rs b/src/bit_manipulation/highest_set_bit.rs index 4952c56be09..3488f49a7d9 100644 --- a/src/bit_manipulation/highest_set_bit.rs +++ b/src/bit_manipulation/highest_set_bit.rs @@ -1,15 +1,18 @@ -// Find Highest Set Bit in Rust -// This code provides a function to calculate the position (or index) of the most significant bit set to 1 in a given integer. - -// Define a function to find the highest set bit. -pub fn find_highest_set_bit(num: i32) -> Option { - if num < 0 { - // Input cannot be negative. - panic!("Input cannot be negative"); - } - +//! This module provides a function to find the position of the most significant bit (MSB) +//! set to 1 in a given positive integer. + +/// Finds the position of the highest (most significant) set bit in a positive integer. +/// +/// # Arguments +/// +/// * `num` - An integer value for which the highest set bit will be determined. +/// +/// # Returns +/// +/// * Returns `Some(position)` if a set bit exists or `None` if no bit is set. +pub fn find_highest_set_bit(num: usize) -> Option { if num == 0 { - return None; // No bit is set, return None. + return None; } let mut position = 0; @@ -27,22 +30,23 @@ pub fn find_highest_set_bit(num: i32) -> Option { mod tests { use super::*; - #[test] - fn test_positive_number() { - let num = 18; - assert_eq!(find_highest_set_bit(num), Some(4)); - } - - #[test] - fn test_zero() { - let num = 0; - assert_eq!(find_highest_set_bit(num), None); + macro_rules! test_find_highest_set_bit { + ($($name:ident: $test_case:expr,)*) => { + $( + #[test] + fn $name() { + let (input, expected) = $test_case; + assert_eq!(find_highest_set_bit(input), expected); + } + )* + }; } - #[test] - #[should_panic(expected = "Input cannot be negative")] - fn test_negative_number() { - let num = -12; - find_highest_set_bit(num); + test_find_highest_set_bit! { + test_positive_number: (18, Some(4)), + test_0: (0, None), + test_1: (1, Some(0)), + test_2: (2, Some(1)), + test_3: (3, Some(1)), } } diff --git a/src/bit_manipulation/sum_of_two_integers.rs b/src/bit_manipulation/sum_of_two_integers.rs index 079ac4c3177..45d3532b173 100644 --- a/src/bit_manipulation/sum_of_two_integers.rs +++ b/src/bit_manipulation/sum_of_two_integers.rs @@ -1,19 +1,22 @@ -/** - * This algorithm demonstrates how to add two integers without using the + operator - * but instead relying on bitwise operations, like bitwise XOR and AND, to simulate - * the addition. It leverages bit manipulation to compute the sum efficiently. - */ +//! This module provides a function to add two integers without using the `+` operator. +//! It relies on bitwise operations (XOR and AND) to compute the sum, simulating the addition process. -pub fn add_two_integers(a: i32, b: i32) -> i32 { - let mut a = a; - let mut b = b; +/// Adds two integers using bitwise operations. +/// +/// # Arguments +/// +/// * `a` - The first integer to be added. +/// * `b` - The second integer to be added. +/// +/// # Returns +/// +/// * `isize` - The result of adding the two integers. +pub fn add_two_integers(mut a: isize, mut b: isize) -> isize { let mut carry; - let mut sum; - // Iterate until there is no carry left while b != 0 { - sum = a ^ b; // XOR operation to find the sum without carry - carry = (a & b) << 1; // AND operation to find the carry, shifted left by 1 + let sum = a ^ b; + carry = (a & b) << 1; a = sum; b = carry; } @@ -23,26 +26,30 @@ pub fn add_two_integers(a: i32, b: i32) -> i32 { #[cfg(test)] mod tests { - use super::add_two_integers; + use super::*; - #[test] - fn test_add_two_integers_positive() { - assert_eq!(add_two_integers(3, 5), 8); - assert_eq!(add_two_integers(100, 200), 300); - assert_eq!(add_two_integers(65535, 1), 65536); + macro_rules! test_add_two_integers { + ($($name:ident: $test_case:expr,)*) => { + $( + #[test] + fn $name() { + let (a, b) = $test_case; + assert_eq!(add_two_integers(a, b), a + b); + assert_eq!(add_two_integers(b, a), a + b); + } + )* + }; } - #[test] - fn test_add_two_integers_negative() { - assert_eq!(add_two_integers(-10, 6), -4); - assert_eq!(add_two_integers(-50, -30), -80); - assert_eq!(add_two_integers(-1, -1), -2); - } - - #[test] - fn test_add_two_integers_zero() { - assert_eq!(add_two_integers(0, 0), 0); - assert_eq!(add_two_integers(0, 42), 42); - assert_eq!(add_two_integers(0, -42), -42); + test_add_two_integers! { + test_add_two_integers_positive: (3, 5), + test_add_two_integers_large_positive: (100, 200), + test_add_two_integers_edge_positive: (65535, 1), + test_add_two_integers_negative: (-10, 6), + test_add_two_integers_both_negative: (-50, -30), + test_add_two_integers_edge_negative: (-1, -1), + test_add_two_integers_zero: (0, 0), + test_add_two_integers_zero_with_positive: (0, 42), + test_add_two_integers_zero_with_negative: (0, -42), } }