Skip to content

Commit 6d61ab3

Browse files
committed
Added another approach for the calculation
1 parent 03aaa9c commit 6d61ab3

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

core-java-modules/core-java-numbers-7/src/main/java/com/baeldung/twoscomplement/TwosComplement.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.baeldung.twoscomplement;
22

33
import java.math.BigInteger;
4+
import java.util.stream.Collectors;
45

56
public class TwosComplement {
67

@@ -74,6 +75,41 @@ private static boolean canRepresentInNBits(BigInteger number, int numBits) {
7475
return number.compareTo(minValue) >= 0 && number.compareTo(maxValue) <= 0;
7576
}
7677

78+
public static String decimalToTwosComplementBinaryUsingShortCut(BigInteger num, int numBits) {
79+
if (!canRepresentInNBits(num, numBits)) {
80+
throw new IllegalArgumentException(numBits + " bits is not enough to represent the number " + num);
81+
}
82+
var isNegative = num.signum() == -1;
83+
var absNum = num.abs();
84+
85+
// Convert the abs value of the number to its binary representation
86+
String binary = absNum.toString(2);
87+
88+
// Pad the binary representation with zeros to make it numBits long
89+
while (binary.length() < numBits) {
90+
binary = "0" + binary;
91+
}
92+
93+
// If the input number is negative, calculate two's complement
94+
if (isNegative) {
95+
binary = performTwosComplementUsingShortCut(binary);
96+
}
97+
98+
return formatInNibbles(binary);
99+
}
100+
101+
private static String performTwosComplementUsingShortCut(String binary) {
102+
int firstOneIndexFromRight = binary.lastIndexOf('1');
103+
if (firstOneIndexFromRight == -1) {
104+
return binary;
105+
}
106+
String rightPart = binary.substring(firstOneIndexFromRight);
107+
String leftPart = binary.substring(0, firstOneIndexFromRight);
108+
String leftWithOnes = leftPart.chars().mapToObj(c -> c == '0' ? '1' : '0')
109+
.map(String::valueOf).collect(Collectors.joining(""));
110+
return leftWithOnes + rightPart;
111+
}
112+
77113
}
78114

79115

core-java-modules/core-java-numbers-7/src/test/java/com/baeldung/twoscomplement/TwosComplementUnitTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,21 @@ public void givenNumberAndBits_getTwosComplement(String number, int noOfBits, St
2424
Assertions.assertEquals(expected, twosComplement);
2525
}
2626

27+
@ParameterizedTest(name = "Twos Complement of {0} with number of bits {1}")
28+
@CsvSource({
29+
"0, 4, 0000",
30+
"1, 4, 0001",
31+
"-1, 4, 1111",
32+
"7, 4, 0111",
33+
"-7, 4, 1001",
34+
"12345, 16, 0011 0000 0011 1001",
35+
"-12345, 16, 1100 1111 1100 0111"
36+
})
37+
public void givenNumberAndBits_getTwosComplementUsingShortcut(String number, int noOfBits, String expected) {
38+
String twosComplement = TwosComplement.decimalToTwosComplementBinary(new BigInteger(number), noOfBits);
39+
Assertions.assertEquals(expected, twosComplement);
40+
}
41+
2742
@Test
2843
public void givenNumberOutsideBitsRange_throwException() {
2944
Exception ex = Assertions.assertThrows(IllegalArgumentException.class, () -> {

0 commit comments

Comments
 (0)