I'm trying to learn Java, so I'm doing a few exercises from a programmer project idea book. This exercise requires that the program be able to convert a decimal number to binary and vice versa, like so:
Please enter the binary/decimal number to convert:9783569 100101010100100100010001 Please enter the binary/decimal number to convert:100101010100100100010001 9783569
Here's the code I came up with:
import java.util.Scanner;
public class BinaryToDecimalAndBackConverter{
static String convertDecimalToBinary(String decimal){
int integer = Integer.valueOf(decimal);
String result = new String();
while(integer > 0){
result+=String.valueOf(integer%2);
integer/=2;
}
result = new StringBuffer(result).reverse().toString();
return result;
}
static int convertBinaryToDecimal(String binary){
int result = 0;
for(int reverseCounter = 0; reverseCounter < binary.length(); reverseCounter++){
char currentChar = binary.charAt(binary.length() - reverseCounter - 1);
int numericValue = Character.getNumericValue(currentChar);
result+=Math.pow(2, reverseCounter) * numericValue;
// System.out.println(Math.pow(2, reverseCounter) * Character.getNumericValue(binary.charAt(binary.length() - reverseCounter - 1)) + " reverseCounter " + reverseCounter);
}
return result;
}
static String isDecimalOrBinary(String input){
for(int counter = 0; counter < input.length(); counter++){
if(input.charAt(counter) != '0' && input.charAt(counter) != '1'){
return "decimal";
}
}
return "binary";
}
public static void main(String[] args){
Scanner inputScanner = new Scanner(System.in);
System.out.print("Please enter the binary/decimal number to convert:");
String input = inputScanner.nextLine();
switch(isDecimalOrBinary(input)){
case "decimal":
System.out.println(convertDecimalToBinary(input));
break;
case "binary":
System.out.println(convertBinaryToDecimal(input));
break;
}
}
}
2 Answers 2
In addition to @Francesco Pitzalis's answer...
String
concatenation
String result = new String();
This is never required as String
s are immutable in Java. If you find yourself using it to append String
values, then you should be using StringBuilder
(the faster, non-synchronized version of StringBuffer
, which is usually recommended unless you require the multi-threading safety of the latter):
StringBuilder result = new StringBuilder();
// ...
result.append(integer % 2); // add some spaces for readability
// ...
return result.reverse().toString();
try-with-resources
// don't forget to close the Scanner
inputScanner.close();
Since you are on Java 7 at least (from the use of String
in switch
), you should be using try-with-resources
to safely and efficiently manage the underlying I/O resource used by your Scanner
instance:
try (Scanner scanner = new Scanner(System.in)) {
// ...
}
Choices and enum
s
On a related note to your isDecimalOrBinary()
method (which @Francesco Pitzalis's answer made a very good point), the return type can also be modeled as an enum
should you still choose to keep it:
enum ValueType {
DECIMAL, BINARY;
public static ValueType parse(String value) {
// ...
}
}
This eliminates the possibility of typos in your expected String
return values, e.g. when you return "decimal"
but are wrongly checking for "Decimal"
from calling the method.
-
1\$\begingroup\$ Code review never fails to teach me more about Java :). Thanks for your answer, especially for the try-with-resources part. \$\endgroup\$Sky– Sky2016年01月19日 04:26:28 +00:00Commented Jan 19, 2016 at 4:26
The best way to do it:
static String convertDecimalToBinary(String decimal) {
return Integer.toString(Integer.parseInt(decimal, 10), 2);
}
static int convertBinaryToDecimal(String binary) {
return Integer.parseInt(binary, 2);
}
By the way your code looks good except for at least two issues:
- Don't work with negative numbers
- The method
isDecimalOrBinary
is ambiguous: what's the result of the100
input? It'sbinary
of course, but if i meant one hundred? I suggest to delegate the user to specify it.
I would correct it in this way:
import java.util.Scanner;
public class BinaryToDecimalAndBackConverter {
static String convertDecimalToBinary(String decimal) {
final boolean isNegative = decimal.startsWith("-");
if (isNegative) {
decimal = decimal.substring(1);
}
int integer = Integer.valueOf(decimal);
String result = new String();
while (integer > 0) {
result += String.valueOf(integer % 2);
integer /= 2;
}
// use StringBuilder instead of StringBuffer, we are sure about
// exclusive access, no need to use a thread safe class
final StringBuilder resultBuilder = new StringBuilder(result);
if (isNegative) {
resultBuilder.append("-");
}
return resultBuilder.reverse().toString();
}
static int convertBinaryToDecimal(String binary) {
final boolean isNegative = binary.startsWith("-");
if (isNegative) {
binary = binary.substring(1);
}
int result = 0;
for (int reverseCounter = 0; reverseCounter < binary.length(); reverseCounter++) {
final char currentChar = binary.charAt(binary.length() - reverseCounter - 1);
final int numericValue = Character.getNumericValue(currentChar);
result += Math.pow(2, reverseCounter) * numericValue;
// System.out.println(Math.pow(2, reverseCounter) *
// Character.getNumericValue(binary.charAt(binary.length() -
// reverseCounter - 1)) + " reverseCounter " + reverseCounter);
}
if (isNegative) {
result = -result;
}
return result;
}
public static void main(String[] args) {
final Scanner inputScanner = new Scanner(System.in);
System.out.print("Please enter the binary/decimal number to convert:");
// expected input: NUM D|B
final String[] splittedInput = inputScanner.nextLine().split(" ");
if (splittedInput.length != 2) {
// don't forget to close the Scanner
inputScanner.close();
throw new IllegalArgumentException("Wrong input format: expected NUM D|B");
}
final String input = splittedInput[0];
switch (splittedInput[1]) {
case "d":
case "D":
System.out.println(convertDecimalToBinary(input));
break;
case "b":
case "B":
System.out.println(convertBinaryToDecimal(input));
break;
default:
// don't forget to close the Scanner
inputScanner.close();
throw new IllegalArgumentException(
"Wrong input format: expected NUM D|B, the second argument was not D nor B");
}
// don't forget to close the Scanner
inputScanner.close();
}
}
-
1\$\begingroup\$ I didn't even consider the 100 case, so thanks for catching it and the unclosed scanner for me :). If only I had known how easy it is to convert the different number systems...I need to read more documentation. If no other answer come up, I'll accept this one :) \$\endgroup\$Sky– Sky2016年01月18日 17:32:07 +00:00Commented Jan 18, 2016 at 17:32