|
package converter; |
|
|
|
/** |
|
* Class utility for converting numbers to binary and back |
|
* Addition and subtraction works for positive numbers |
|
* Converter works right. Converter use two's complement for negative numbers |
|
* <b>Functions:</b> |
|
* <ul> |
|
* <li>Converting integer to binary string</li> |
|
* <li>Converting floating point (double) to binary string</li> |
|
* <li>Addition binary string numbers</li> |
|
* <li>Subtraction binary string numbers</li> |
|
* </ul> |
|
* |
|
* @author tkaczenko |
|
* @see <a href="https://en.wikipedia.org/wiki/Two%27s_complement">https://en.wikipedia.org/wiki/Two%27s_complement</a> |
|
*/ |
|
public class Binary { |
|
/** |
|
* Addition for binary string numbers |
|
* |
|
* @param s1 Binary string created with {@code Binary} |
|
* @param s2 Binary string created with {@code Binary} |
|
* @return Binary string as a result of addition |
|
*/ |
|
public static String addition(String s1, String s2) { |
|
if (s1 == null || s2 == null) return ""; |
|
|
|
// Addition algorithm for binary numbers |
|
int first = s1.length() - 1; |
|
int second = s2.length() - 1; |
|
StringBuilder sb = new StringBuilder(); |
|
int carry = 0; |
|
while (first >= 0 || second >= 0) { |
|
int sum = carry; |
|
if (first >= 0) { |
|
sum += s1.charAt(first) - '0'; |
|
first--; |
|
} |
|
if (second >= 0) { |
|
sum += s2.charAt(second) - '0'; |
|
second--; |
|
} |
|
carry = sum >> 1; |
|
sum = sum & 1; |
|
sb.append(sum == 0 ? '0' : '1'); |
|
} |
|
if (carry > 0) { |
|
sb.append('1'); |
|
} |
|
|
|
sb.reverse(); |
|
|
|
/// FIXME: 15.10.16 Fix subtraction for positive and negative numbers using addition |
|
// Only for subtraction positive number |
|
if (s1.charAt(0) == '1' && s2.charAt(0) == '1') { |
|
sb.setCharAt(0, '1'); |
|
} else { |
|
sb.setCharAt(0, '0'); |
|
} |
|
|
|
return sb.toString(); |
|
} |
|
|
|
/** |
|
* Subtraction for binary string numbers |
|
* |
|
* @param s1 Binary string created with {@code Binary} |
|
* @param s2 Binary string created with {@code Binary} |
|
* @return Binary string as a result of subtraction |
|
*/ |
|
public static String subtraction(String s1, String s2) { |
|
// Change sign of second number to use addition |
|
char c = (s2.charAt(0) == 1) ? '0' : '1'; |
|
s2 = c + s2.substring(1); |
|
return addition(getTwosComplement(s1), getTwosComplement(s2)); |
|
} |
|
|
|
public static String toBinary(double n) { |
|
String decimal = toBinary((int) n); |
|
double fraction = n - ((int) n); |
|
String val = decimal + "."; |
|
if (fraction < 0) { |
|
val += "0"; |
|
} |
|
while (fraction > 0) { |
|
double r = fraction * 2; |
|
if (r >= 1) { |
|
val += "1"; |
|
fraction = r - 1; |
|
} else { |
|
val += "0"; |
|
fraction = r; |
|
} |
|
} |
|
return val; |
|
} |
|
|
|
public static String toBinary(int num) { |
|
StringBuilder stringBuilder = new StringBuilder(); |
|
boolean isNegative = (num < 0); |
|
if (isNegative) { |
|
num = Math.abs(num); |
|
} |
|
while (num > 0) { |
|
stringBuilder.insert(0, num & 1); |
|
num >>= 1; |
|
} |
|
// If number < 7 add zero and next add sign cell |
|
for (int i = stringBuilder.length() - 1; i < 7; i++) { |
|
stringBuilder.insert(0, "0"); |
|
} |
|
if (isNegative) { |
|
stringBuilder.insert(0, "1"); |
|
} else { |
|
stringBuilder.insert(0, "0"); |
|
} |
|
if (stringBuilder.length() == 0) { |
|
stringBuilder.append("0"); |
|
} |
|
return stringBuilder.toString(); |
|
} |
|
|
|
public static int toDecimal(String str) { |
|
double val = 0; |
|
int k = 1; |
|
if (str.charAt(0) == '1') { |
|
k = -1; |
|
} |
|
for (int i = 1; i < str.length(); i++) { |
|
if (str.charAt(i) == '1') { |
|
val += Math.pow(2, str.length() - 1 - i); |
|
} |
|
} |
|
val *= k; |
|
return (int) val; |
|
} |
|
|
|
/** |
|
* Get two's complement for binary negative number |
|
* |
|
* @param binaryInt Binary string created with {@code Binary} |
|
* @return String of two's complement |
|
*/ |
|
private static String getTwosComplement(String binaryInt) { |
|
if (binaryInt.charAt(0) == '1') { |
|
String invertedInt = invertDigits(binaryInt); |
|
return addition(invertedInt, "1"); |
|
} else { |
|
return binaryInt; |
|
} |
|
} |
|
|
|
private static String invertDigits(String binaryInt) { |
|
StringBuilder stringBuilder = new StringBuilder(binaryInt); |
|
for (int i = 1; i < stringBuilder.length(); i++) { |
|
if (stringBuilder.charAt(i) == '1') { |
|
stringBuilder.setCharAt(i, '0'); |
|
} else { |
|
stringBuilder.setCharAt(i, '1'); |
|
} |
|
} |
|
return stringBuilder.toString(); |
|
} |
|
} |