|
| 1 | +//! Binary Coded Decimal (BCD) conversion |
| 2 | +//! |
| 3 | +//! This module provides a function to convert decimal integers to Binary Coded Decimal (BCD) format. |
| 4 | +//! In BCD, each decimal digit is represented by its 4-bit binary equivalent. |
| 5 | +//! |
| 6 | +//! # Examples |
| 7 | +//! |
| 8 | +//! ``` |
| 9 | +//! use the_algorithms_rust::bit_manipulation::binary_coded_decimal; |
| 10 | +//! |
| 11 | +//! assert_eq!(binary_coded_decimal(12), "0b00010010"); |
| 12 | +//! assert_eq!(binary_coded_decimal(987), "0b100110000111"); |
| 13 | +//! ``` |
| 14 | +
|
| 15 | +use std::fmt::Write; |
| 16 | + |
| 17 | +/// Converts a decimal integer to Binary Coded Decimal (BCD) format. |
| 18 | +/// |
| 19 | +/// Each digit of the input number is represented by a 4-bit binary value. |
| 20 | +/// Negative numbers are treated as 0. |
| 21 | +/// |
| 22 | +/// # Arguments |
| 23 | +/// |
| 24 | +/// * `number` - An integer to be converted to BCD format |
| 25 | +/// |
| 26 | +/// # Returns |
| 27 | +/// |
| 28 | +/// A `String` representing the BCD encoding with "0b" prefix |
| 29 | +/// |
| 30 | +/// # Examples |
| 31 | +/// |
| 32 | +/// ``` |
| 33 | +/// use the_algorithms_rust::bit_manipulation::binary_coded_decimal; |
| 34 | +/// |
| 35 | +/// assert_eq!(binary_coded_decimal(0), "0b0000"); |
| 36 | +/// assert_eq!(binary_coded_decimal(3), "0b0011"); |
| 37 | +/// assert_eq!(binary_coded_decimal(12), "0b00010010"); |
| 38 | +/// assert_eq!(binary_coded_decimal(987), "0b100110000111"); |
| 39 | +/// assert_eq!(binary_coded_decimal(-5), "0b0000"); |
| 40 | +/// ``` |
| 41 | +/// |
| 42 | +/// # Algorithm |
| 43 | +/// |
| 44 | +/// 1. Convert the number to its absolute value (negative numbers become 0) |
| 45 | +/// 2. For each decimal digit: |
| 46 | +/// - Convert the digit to binary |
| 47 | +/// - Pad to 4 bits with leading zeros |
| 48 | +/// - Concatenate to the result |
| 49 | +/// 3. Prepend "0b" to the final binary string |
| 50 | +pub fn binary_coded_decimal(number: i32) -> String { |
| 51 | + // Handle negative numbers by converting to 0 |
| 52 | + let num = if number < 0 { 0 } else { number }; |
| 53 | + |
| 54 | + // Convert to string to process each digit |
| 55 | + let digits = num.to_string(); |
| 56 | + |
| 57 | + // Build the BCD string using fold for efficiency |
| 58 | + let bcd = digits.chars().fold(String::new(), |mut acc, digit| { |
| 59 | + // Convert char to digit value and format as 4-bit binary |
| 60 | + let digit_value = digit.to_digit(10).unwrap(); |
| 61 | + write!(acc, "{digit_value:04b}").unwrap(); |
| 62 | + acc |
| 63 | + }); |
| 64 | + |
| 65 | + format!("0b{bcd}") |
| 66 | +} |
| 67 | + |
| 68 | +#[cfg(test)] |
| 69 | +mod tests { |
| 70 | + use super::*; |
| 71 | + |
| 72 | + #[test] |
| 73 | + fn test_zero() { |
| 74 | + assert_eq!(binary_coded_decimal(0), "0b0000"); |
| 75 | + } |
| 76 | + |
| 77 | + #[test] |
| 78 | + fn test_single_digit() { |
| 79 | + assert_eq!(binary_coded_decimal(1), "0b0001"); |
| 80 | + assert_eq!(binary_coded_decimal(2), "0b0010"); |
| 81 | + assert_eq!(binary_coded_decimal(3), "0b0011"); |
| 82 | + assert_eq!(binary_coded_decimal(4), "0b0100"); |
| 83 | + assert_eq!(binary_coded_decimal(5), "0b0101"); |
| 84 | + assert_eq!(binary_coded_decimal(6), "0b0110"); |
| 85 | + assert_eq!(binary_coded_decimal(7), "0b0111"); |
| 86 | + assert_eq!(binary_coded_decimal(8), "0b1000"); |
| 87 | + assert_eq!(binary_coded_decimal(9), "0b1001"); |
| 88 | + } |
| 89 | + |
| 90 | + #[test] |
| 91 | + fn test_two_digits() { |
| 92 | + assert_eq!(binary_coded_decimal(10), "0b00010000"); |
| 93 | + assert_eq!(binary_coded_decimal(12), "0b00010010"); |
| 94 | + assert_eq!(binary_coded_decimal(25), "0b00100101"); |
| 95 | + assert_eq!(binary_coded_decimal(99), "0b10011001"); |
| 96 | + } |
| 97 | + |
| 98 | + #[test] |
| 99 | + fn test_three_digits() { |
| 100 | + assert_eq!(binary_coded_decimal(100), "0b000100000000"); |
| 101 | + assert_eq!(binary_coded_decimal(123), "0b000100100011"); |
| 102 | + assert_eq!(binary_coded_decimal(456), "0b010001010110"); |
| 103 | + assert_eq!(binary_coded_decimal(987), "0b100110000111"); |
| 104 | + } |
| 105 | + |
| 106 | + #[test] |
| 107 | + fn test_large_numbers() { |
| 108 | + assert_eq!(binary_coded_decimal(1234), "0b0001001000110100"); |
| 109 | + assert_eq!(binary_coded_decimal(9999), "0b1001100110011001"); |
| 110 | + } |
| 111 | + |
| 112 | + #[test] |
| 113 | + fn test_negative_numbers() { |
| 114 | + // Negative numbers should be treated as 0 |
| 115 | + assert_eq!(binary_coded_decimal(-1), "0b0000"); |
| 116 | + assert_eq!(binary_coded_decimal(-2), "0b0000"); |
| 117 | + assert_eq!(binary_coded_decimal(-100), "0b0000"); |
| 118 | + } |
| 119 | + |
| 120 | + #[test] |
| 121 | + fn test_each_digit_encoding() { |
| 122 | + // Verify that each digit is encoded correctly in a multi-digit number |
| 123 | + // 67 should be: 6 (0110) and 7 (0111) |
| 124 | + assert_eq!(binary_coded_decimal(67), "0b01100111"); |
| 125 | + |
| 126 | + // 305 should be: 3 (0011), 0 (0000), 5 (0101) |
| 127 | + assert_eq!(binary_coded_decimal(305), "0b001100000101"); |
| 128 | + } |
| 129 | +} |
0 commit comments