Skip to content

Refactor BCD Conversion docs and add more tests #5762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 13, 2024
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
Original file line number Diff line number Diff line change
@@ -1,56 +1,80 @@
package com.thealgorithms.bitmanipulation;

/**
* This class provides methods to convert between BCD (Binary-Coded Decimal) and binary.
* This class provides methods to convert between BCD (Binary-Coded Decimal) and decimal numbers.
*
* Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
* BCD is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
*
* For more information, refer to the
* <a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">Binary-Coded Decimal</a> Wikipedia page.
*
* <b>Example usage:</b>
* <pre>
* int binary = BcdConversion.bcdToBinary(0x1234);
* System.out.println("BCD 0x1234 to binary: " + binary); // Output: 1234
* int decimal = BcdConversion.bcdToDecimal(0x1234);
* System.out.println("BCD 0x1234 to decimal: " + decimal); // Output: 1234
*
* int bcd = BcdConversion.binaryToBcd(1234);
* System.out.println("Binary 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
* int bcd = BcdConversion.decimalToBcd(1234);
* System.out.println("Decimal 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
* </pre>
*/
public final class BcdConversion {
private BcdConversion() {
}

/**
* Converts a BCD (Binary-Coded Decimal) number to binary.
* Converts a BCD (Binary-Coded Decimal) number to a decimal number.
* <p>Steps:
* <p>1. Validate the BCD number to ensure all digits are between 0 and 9.
* <p>2. Extract the last 4 bits (one BCD digit) from the BCD number.
* <p>3. Multiply the extracted digit by the corresponding power of 10 and add it to the decimal number.
* <p>4. Shift the BCD number right by 4 bits to process the next BCD digit.
* <p>5. Repeat steps 1-4 until the BCD number is zero.
*
* @param bcd The BCD number.
* @return The corresponding binary number.
* @return The corresponding decimal number.
* @throws IllegalArgumentException if the BCD number contains invalid digits.
*/
public static int bcdToBinary(int bcd) {
int binary = 0;
public static int bcdToDecimal(int bcd) {
int decimal = 0;
int multiplier = 1;

// Validate BCD digits
while (bcd > 0) {
int digit = bcd & 0xF; // Extract the last 4 bits (one BCD digit)
binary += digit * multiplier;
int digit = bcd & 0xF;
if (digit > 9) {
throw new IllegalArgumentException("Invalid BCD digit: " + digit);
}
decimal += digit * multiplier;
multiplier *= 10;
bcd >>= 4; // Shift right by 4 bits to process the next BCD digit
bcd >>= 4;
}
return binary;
return decimal;
}

/**
* Converts a binary number to BCD (Binary-Coded Decimal).
* Converts a decimal number to BCD (Binary-Coded Decimal).
* <p>Steps:
* <p>1. Check if the decimal number is within the valid range for BCD (0 to 9999).
* <p>2. Extract the last decimal digit from the decimal number.
* <p>3. Shift the digit to the correct BCD position and add it to the BCD number.
* <p>4. Remove the last decimal digit from the decimal number.
* <p>5. Repeat steps 2-4 until the decimal number is zero.
*
* @param binary The binary number.
* @param decimal The decimal number.
* @return The corresponding BCD number.
* @throws IllegalArgumentException if the decimal number is greater than 9999.
*/
public static int binaryToBcd(int binary) {
public static int decimalToBcd(int decimal) {
if (decimal < 0 || decimal > 9999) {
throw new IllegalArgumentException("Value out of bounds for BCD representation: " + decimal);
}

int bcd = 0;
int shift = 0;
while (binary > 0) {
int digit = binary % 10; // Extract the last decimal digit
bcd |= (digit << (shift * 4)); // Shift the digit to the correct BCD position
binary /= 10; // Remove the last decimal digit
while (decimal > 0) {
int digit = decimal % 10;
bcd |= (digit << (shift * 4));
decimal /= 10;
shift++;
}
return bcd;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,65 +1,85 @@
package com.thealgorithms.bitmanipulation;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

/**
* Unit tests for the BcdConversion class.
*/
public class BcdConversionTest {

/**
* Test the bcdToBinary method with a BCD number.
*/
@Test
public void testBcdToBinary() {
int binary = BcdConversion.bcdToBinary(0x1234);
assertEquals(1234, binary); // BCD 0x1234 should convert to binary 1234
public void testBcdToDecimal() {
int decimal = BcdConversion.bcdToDecimal(0x1234);
assertEquals(1234, decimal); // BCD 0x1234 should convert to decimal 1234
}

/**
* Test the binaryToBcd method with a binary number.
*/
@Test
public void testBinaryToBcd() {
int bcd = BcdConversion.binaryToBcd(1234);
assertEquals(0x1234, bcd); // Binary 1234 should convert to BCD 0x1234
public void testDecimalToBcd() {
int bcd = BcdConversion.decimalToBcd(1234);
assertEquals(0x1234, bcd); // Decimal 1234 should convert to BCD 0x1234
}

/**
* Test the bcdToBinary method with zero.
*/
@Test
public void testBcdToBinaryZero() {
int binary = BcdConversion.bcdToBinary(0x0);
assertEquals(0, binary); // BCD 0x0 should convert to binary 0
public void testBcdToDecimalZero() {
int decimal = BcdConversion.bcdToDecimal(0x0);
assertEquals(0, decimal); // BCD 0x0 should convert to decimal 0
}

/**
* Test the binaryToBcd method with zero.
*/
@Test
public void testBinaryToBcdZero() {
int bcd = BcdConversion.binaryToBcd(0);
assertEquals(0x0, bcd); // Binary 0 should convert to BCD 0x0
public void testDecimalToBcdZero() {
int bcd = BcdConversion.decimalToBcd(0);
assertEquals(0x0, bcd); // Decimal 0 should convert to BCD 0x0
}

/**
* Test the bcdToBinary method with a single digit BCD number.
*/
@Test
public void testBcdToBinarySingleDigit() {
int binary = BcdConversion.bcdToBinary(0x7);
assertEquals(7, binary); // BCD 0x7 should convert to binary 7
public void testBcdToDecimalSingleDigit() {
int decimal = BcdConversion.bcdToDecimal(0x7);
assertEquals(7, decimal); // BCD 0x7 should convert to decimal 7
}

/**
* Test the binaryToBcd method with a single digit binary number.
*/
@Test
public void testBinaryToBcdSingleDigit() {
int bcd = BcdConversion.binaryToBcd(7);
assertEquals(0x7, bcd); // Binary 7 should convert to BCD 0x7
public void testDecimalToBcdSingleDigit() {
int bcd = BcdConversion.decimalToBcd(7);
assertEquals(0x7, bcd); // Decimal 7 should convert to BCD 0x7
}

@Test
public void testBcdToDecimalMaxValue() {
int decimal = BcdConversion.bcdToDecimal(0x9999);
assertEquals(9999, decimal); // BCD 0x9999 should convert to decimal 9999
}

@Test
public void testDecimalToBcdMaxValue() {
int bcd = BcdConversion.decimalToBcd(9999);
assertEquals(0x9999, bcd); // Decimal 9999 should convert to BCD 0x9999
}

@Test
public void testBcdToDecimalInvalidHighDigit() {
// Testing invalid BCD input where one of the digits is > 9
assertThrows(IllegalArgumentException.class, () -> {
BcdConversion.bcdToDecimal(0x123A); // Invalid BCD, 'A' is not a valid digit
});
}

@Test
public void testDecimalToBcdInvalidValue() {
// Testing conversion for numbers greater than 9999, which cannot be represented in BCD
assertThrows(IllegalArgumentException.class, () -> {
BcdConversion.decimalToBcd(10000); // 10000 is too large for BCD representation
});
}

@Test
public void testBcdToDecimalLeadingZeroes() {
int decimal = BcdConversion.bcdToDecimal(0x0234);
assertEquals(234, decimal); // BCD 0x0234 should convert to decimal 234, ignoring leading zero
}

@Test
public void testDecimalToBcdLeadingZeroes() {
int bcd = BcdConversion.decimalToBcd(234);
assertEquals(0x0234, bcd); // Decimal 234 should convert to BCD 0x0234
}
}