|
1 | 1 | package com.baeldung.twoscomplement; |
2 | 2 |
|
3 | 3 | import java.math.BigInteger; |
| 4 | +import java.util.stream.Collectors; |
4 | 5 |
|
5 | 6 | public class TwosComplement { |
6 | 7 |
|
@@ -74,6 +75,41 @@ private static boolean canRepresentInNBits(BigInteger number, int numBits) { |
74 | 75 | return number.compareTo(minValue) >= 0 && number.compareTo(maxValue) <= 0; |
75 | 76 | } |
76 | 77 |
|
| 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 | + |
77 | 113 | } |
78 | 114 |
|
79 | 115 |
|
|
0 commit comments