Added another approach for the calculation

This commit is contained in:
Yadukrishnan 2024-04-25 09:44:27 +05:30
parent 03aaa9ceeb
commit 6d61ab3761
2 changed files with 51 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package com.baeldung.twoscomplement;
import java.math.BigInteger;
import java.util.stream.Collectors;
public class TwosComplement {
@ -74,6 +75,41 @@ public class TwosComplement {
return number.compareTo(minValue) >= 0 && number.compareTo(maxValue) <= 0;
}
public static String decimalToTwosComplementBinaryUsingShortCut(BigInteger num, int numBits) {
if (!canRepresentInNBits(num, numBits)) {
throw new IllegalArgumentException(numBits + " bits is not enough to represent the number " + num);
}
var isNegative = num.signum() == -1;
var absNum = num.abs();
// Convert the abs value of the number to its binary representation
String binary = absNum.toString(2);
// Pad the binary representation with zeros to make it numBits long
while (binary.length() < numBits) {
binary = "0" + binary;
}
// If the input number is negative, calculate two's complement
if (isNegative) {
binary = performTwosComplementUsingShortCut(binary);
}
return formatInNibbles(binary);
}
private static String performTwosComplementUsingShortCut(String binary) {
int firstOneIndexFromRight = binary.lastIndexOf('1');
if (firstOneIndexFromRight == -1) {
return binary;
}
String rightPart = binary.substring(firstOneIndexFromRight);
String leftPart = binary.substring(0, firstOneIndexFromRight);
String leftWithOnes = leftPart.chars().mapToObj(c -> c == '0' ? '1' : '0')
.map(String::valueOf).collect(Collectors.joining(""));
return leftWithOnes + rightPart;
}
}

View File

@ -24,6 +24,21 @@ public class TwosComplementUnitTest {
Assertions.assertEquals(expected, twosComplement);
}
@ParameterizedTest(name = "Twos Complement of {0} with number of bits {1}")
@CsvSource({
"0, 4, 0000",
"1, 4, 0001",
"-1, 4, 1111",
"7, 4, 0111",
"-7, 4, 1001",
"12345, 16, 0011 0000 0011 1001",
"-12345, 16, 1100 1111 1100 0111"
})
public void givenNumberAndBits_getTwosComplementUsingShortcut(String number, int noOfBits, String expected) {
String twosComplement = TwosComplement.decimalToTwosComplementBinary(new BigInteger(number), noOfBits);
Assertions.assertEquals(expected, twosComplement);
}
@Test
public void givenNumberOutsideBitsRange_throwException() {
Exception ex = Assertions.assertThrows(IllegalArgumentException.class, () -> {