Two Laptop Bag*
The moose likes Java in General and the fly likes Binary to Decimal conversion Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Binary to Decimal conversion" Watch "Binary to Decimal conversion" New topic
Author

Binary to Decimal conversion

Sudhir Srinivasan
Ranch Hand

Joined: Jun 08, 2011
Posts: 90
Hi,

The program below takes input from the user binary values, reads them as a string and converts the same to decimal using the 'Integer' wrapper class.

Issue-faced:

I've used the while loop to take subsequent user inputs and to terminate the program on user entering exit. As the string "exit" is converted to base 10 values (whereas the Integer.parseInt() is expecting an input string with characters to be converted to base 2) , the higher radix throws an NumberFormatException.

code snippet that raises the exception



Is there a way to get around this without doing away with the while loop (& the condition within the loop).

thanks,
Sudhir

Program code:




Program output(on netbeans IDE):

Jon Avadis
Ranch Hand

Joined: Jul 20, 2011
Posts: 49

Hi

You are comparing strings with == / != instead of the "equals"-method. You will find a lot written about why this is a
bad idea if you search this forum or google.

You could make the checks in the while loop easier with a equals-method that ignores Upper/lower case.

Im a beginner myself but i guess its not good practise to use the condition in while to assign your "binary" String.
For me its hard to read and a bad place to "smuggle in" an assignement, but i might be mistaking.


Knowledge Reigns Supreme
Jay Brass
Ranch Hand

Joined: Oct 24, 2000
Posts: 76
Sudhir,

YOu could try wrapping your Integer.parseInt in a try catch like this


You might want to initialize dec to 0 too.

Hope this helps

~J
Jay Brass
Ranch Hand

Joined: Oct 24, 2000
Posts: 76
A better solution


Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3419
    
  12
Jon Avadis wrote:Im a beginner myself but i guess its not good practise to use the condition in while to assign your "binary" String.

It is a bit difficult to understand the first time you see it, but it is commonly used if you are only testing for one value.

It won't work in the OP's case because he is actually reading (up to) three lines from the input and using a different one for each test.


Joanne
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37941
    
  22
I think you are making life difficult for yourself by writing too much code. You should write, compile, run and test, maybe 5 lines. Then add another 5 lines and repeat the exercise.
What is probably happening is that all your == "exit" tests are returning what they are expected to return (ie false throughout), and you are then passing the text "exit" to the Integer.parseInt method.
I would suggest you look through the String class for methods which might make equality testing easier.
Sudhir Srinivasan
Ranch Hand

Joined: Jun 08, 2011
Posts: 90

Thank you Campbell and the other responders - Joanne, Jay and Jon - for your inputs / suggestions.

Campbell Ritchie wrote:I think you are making life difficult for yourself by writing too much code. You should write, compile, run and test, maybe 5 lines. Then add another 5 lines and repeat the exercise.
What is probably happening is that all your == "exit" tests are returning what they are expected to return (ie false throughout), and you are then passing the text "exit" to the Integer.parseInt method.
I would suggest you look through the String class for methods which might make equality testing easier.


Yes, I write lengthy code and I end up missing the obvious! Shall try to stick more to program logic than length in the future.

The equalsIgnoreCase() is the most appropriate in the context of my original code. I also ran the program using the equals(). This works for evaluating a single condition say



but would return false if user entered Exit or EXIT (as the method compares the String object passed to the one input and returns true only if the sequence and casing of characters exactly match)



Joanne NealI wrote:It is a bit difficult to understand the first time you see it, but it is commonly used if you are only testing for one value.


Yes, it would more appropriate while reading an int value (excluding 0) and using 0 for program termination say



However, as per my original code, evaluating one condition (instead of three)



still throws NFE as the "exit" passed to



would convert to int value whose base is higher than the one expected



Jay Brass wrote:A better solution

1. try {
2. while(!(binary = br.readLine()).equalsIgnoreCase("exit") ) {
3. System.out.println("You have input: "+binary);
4.
5. scan.useDelimiter("\n");
6.
7. try {
8. dec = Integer.parseInt(binary, 2);
9. }
10. catch(NumberFormatException nfe){
11. System.out.println("Decimal value is not a number: ");
12. }



Thank you for the code. The program works just fine. I had missed out on user entering by mistake say, 2 or 3 or 4 and so on, apart from binary values or "exit", the try..catch block around the statement



would handle the NFE and display the appropriate message.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37941
    
  22
Sudhir Srinivasan wrote: . . . However, as per my original code, evaluating one condition (instead of three)

. . .
. . . will always return true because the "exit" object entered from the keyboard is guaranteed to be a different object from that in the String pool. That is not caused by evaluating one condition, but by inappropriate use of the != and == operators.

I was hoping you would find equalsIgnoreCase(). Always use an equals method for comparing reference types for identity, never == or !=. The exception to that rule is for members of enums, which are true singletons, where == and != are actually appropriate.

You can find how to convert between binary and decimal numbers here.
Sudhir Srinivasan
Ranch Hand

Joined: Jun 08, 2011
Posts: 90
Campbell Ritchie wrote:. . . will always return true because the "exit" object entered from the keyboard is guaranteed to be a different object from that in the String pool.


If i have understood your point correctly -

At run-time, the java system would construct two objects



and the object references str and binary would reference different objects in the String pool thereby returning true.


Campbell Ritchie wrote:
That is not caused by evaluating one condition, but by inappropriate use of the != and == operators.

I was hoping you would find equalsIgnoreCase(). Always use an equals method for comparing reference types for identity, never == or !=. The exception to that rule is for members of enums, which are true singletons, where == and != are actually appropriate.


The equals method therefore is the right way .

regards,
Sudhir


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37941
    
  22
Afraid nearly, but not quite. There is an object created, the first time a class is loaded which uses the String literal "exit" anywhere. There is a far better explanation of that elsewhere on the Ranch: search for "Strings, literally", and you will find a JavaRanch Journal article about this very topic.

As I said, when the class is loaded, the String object "exit" is created, and put into the String pool. Whenever there is another String which is identical to "exit" as a compile-time constant (I hope this is the correct link), the same String "exit" is found and the same object is used. This confuses beginners, as you will see if you run this code:You will now go round saying that the == operator does work on Strings after all.

When you enter something from the keyboard however, the JVM does not check whether it is already in the String pool, so a second String object equal to "exit" would be created. So, yes, you have got two objects, but they are not really created as you have written. One might occupy memory 456DEF, and will probably be kept on the stack because it is a local variable. The other is probably not on the stack, but in a Map object. There is something somewhere which records which strings are in the String pool, and their location. The most likely type to record such information is a Map.
You can get the second "exit" exchanged for that in the String pool with the intern() method.
Sudhir Srinivasan
Ranch Hand

Joined: Jun 08, 2011
Posts: 90
Campbell Ritchie wrote:As I said, when the class is loaded, the String object "exit" is created, and put into the String pool. Whenever there is another String which is identical to "exit" as a compile-time constant (I hope this is the correct link), the same String "exit" is found and the same object is used. This confuses beginners


It was confusing but the javaranch article (a good one)

Campbell Ritchie wrote:There is a far better explanation of that elsewhere on the Ranch: search for "Strings, literally", and you will find a JavaRanch Journal article about this very topic.


certainly brought clarity on String literals.

Although they are immutable, the key distinction lies in their behavior as String literals initialized (at the time of compiling) as given in your code

variables s and ss, from String pool, referencing same String object


and the resulting output

Output 1


as opposed to their behavior as run-time objects

variables s and sss, from String pool, referencing distinct String objects



with the use of the 'new' keyword and the resulting output.

Output 2


The ambiguity in the above outputs vis-a-vis == operator shows that equals method is best suited for comparing String (object) equality.

Even the intern() method


implicitly uses the equals() for the variables to reference the same object, replacing sss with s given by the below output

init:
deps-jar:
compile-single:
run-single:
Result 2:
false
Campbell
BUILD SUCCESSFUL (total time: 0 seconds)

I will read about Map object and get back to you on that (kindly suggest a ranch article relating to the same for storing String literals, if possible)

thanks and regards,
Sudhir
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37941
    
  22
You can read about Maps here.

In the case of the String pool, you would have code like this... and the Map would contain the String and its String pool representation. It would actually be more like

"Campbell"→"Campbell"in String Pool
Sudhir Srinivasan
Ranch Hand

Joined: Jun 08, 2011
Posts: 90

Hi Campbell

Please find below the program converting binary to decimal using array (and the Math class).

Campbell Ritchie wrote:
You can find how to convert between binary and decimal numbers here.


The program works just fine (as suggested, i wrote the code in segments - writing, compiling, running and testing - and finally testing the entire program).


Program:


However, i wanted it to do the conversion (without the pow() method) i.e using only for loop(s). Lines 38 to 44 have been substituted with the code below.

Modified code:



While the conversion does take place, the result is not correct as the following output(s) show.



In the above modified code, i think the problem is with the second for loop (i may be wrong). If condition, within the loop, calculates correctly in the first iteration but does not do so in the subsequent ones due to -

a) unable to decrement the exponent placeholder 'j' by 1 and
b) variable power to calculate 2^0 = 1 only for the last array element

Any suggestions from you would be of great help!

thanks and regards,
Sudhir


Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37941
    
  22
Pencil and paper. Convert this binary number to decimal
001011010101001010110101010101001110100101010
I don't know the right answer; I simply tapped the keys several times with my eyes shut. Now, how do you do it?
  • @***@ Start with a decimal value of 0.
  • Look at the leftmost binary digit.
  • Add it to your decimal value.
  • Double the decimal value.
  • Delete the leftmost digit from the binary number.
  • If any binary digits remain, go back to @***@
  • 001011010101001010110101010101001110100101010 0
    01011010101001010110101010101001110100101010 0
    1011010101001010110101010101001110100101010 0
    011010101001010110101010101001110100101010 1
    11010101001010110101010101001110100101010 2
    1010101001010110101010101001110100101010 5
    010101001010110101010101001110100101010 11
    10101001010110101010101001110100101010 22
    0101001010110101010101001110100101010 45
    101001010110101010101001110100101010 90
    01001010110101010101001110100101010 181
    1001010110101010101001110100101010 362
    001010110101010101001110100101010 725
    01010110101010101001110100101010 1450
    1010110101010101001110100101010 2900
    010110101010101001110100101010 5801
    10110101010101001110100101010 11802
    0110101010101001110100101010 23605
    110101010101001110100101010 47210
    10101010101001110100101010 94421
    0101010101001110100101010 188843
    101010101001110100101010 377686
    etc etc and the calculator says it should be 6229156601130.
    Try a smaller number first.
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 37941
        
      22
    You can get a char[] from a String "0101010110011010110101010" with one of its methods. You can do arithmetic on chars, eg c - '0'. So you can easily get 1 and 0 out of that String.
    Campbell Ritchie
    Sheriff

    Joined: Oct 13, 2005
    Posts: 37941
        
      22
    Your method with the pow() method call looks inordinately complicated.
    Sudhir Srinivasan
    Ranch Hand

    Joined: Jun 08, 2011
    Posts: 90
    Campbell Ritchie wrote:Pencil and paper. Convert this binary number to decimal
    001011010101001010110101010101001110100101010
    I don't know the right answer; I simply tapped the keys several times with my eyes shut. Now, how do you do it?
  • @***@ Start with a decimal value of 0.
  • Look at the leftmost binary digit.
  • Add it to your decimal value.
  • Double the decimal value.
  • Delete the leftmost digit from the binary number.
  • If any binary digits remain, go back to @***@


  • Thank you for the pseudocode. As i thought, the second for loop was unnecessary (& with wrong logic inside it).

    Given below is the updated code



    and the output with correct decimal values.

    A) Output - for smaller binary numbers



    and

    B) Output - for the binary number 001011010101001010110101010101001110100101010



    In the case of large binary number

    Campbell Ritchie wrote:
    001011010101001010110101010101001110100101010 0
    01011010101001010110101010101001110100101010 0
    1011010101001010110101010101001110100101010 0
    011010101001010110101010101001110100101010 1
    11010101001010110101010101001110100101010 2
    1010101001010110101010101001110100101010 5
    010101001010110101010101001110100101010 11
    10101001010110101010101001110100101010 22
    0101001010110101010101001110100101010 45
    101001010110101010101001110100101010 90
    01001010110101010101001110100101010 181
    1001010110101010101001110100101010 362
    001010110101010101001110100101010 725
    01010110101010101001110100101010 1450
    1010110101010101001110100101010 2900
    010110101010101001110100101010 5801
    10110101010101001110100101010 11802
    0110101010101001110100101010 23605
    110101010101001110100101010 47210
    10101010101001110100101010 94421
    0101010101001110100101010 188843
    101010101001110100101010 377686
    etc etc and the calculator says it should be 6229156601130.
    Try a smaller number first.


    it makes sense to read them together as a String [rather than individually (& as int type)] and then convert to the corresponding decimal value.

    As suggested

    Campbell Ritchie wrote:
    You can get a char[] from a String "0101010110011010110101010" with one of its methods. You can do arithmetic on chars, eg c - '0'. So you can easily get 1 and 0 out of that String.


    I've modified the code such that



    and the resulting correct output



    Campbell Ritchie wrote:
    Your method with the pow() method call looks inordinately complicated.


    I've used the pow() method of the Math class for calculation of the exponentiation part.



    Explanation:
    a) Two arguments are passed to the method being the base value and the exponent (variable j in this case)
    b) i used to retrieve each array element starting with binary[0], binary[1] and so on
    c) number is the index for the no. of user inputs [0s or 1s] that corresponds to the exponent part
    d) j is initialized by number-1 to calculate the exponent part in reverse starting with the most significant binary digit (stored
    in binary[0], next value stored in binary[1] and so on).

    For example, for the binary no. 100, taken stored and retrieved individually, i would evaluate against binary[0]
    containing 1, binary[1] containing 0 and binary[2] containing 0. j on the other hand - as no. of user inputs is 3 - calculates

    1st iteration(j=3-1) - 2^2 (j>power) for binary[0]
    2nd iteration(j-1) - 2^1 (--ditto--) for binary[1]
    3rd iteration(j-1) - 2^0 (value of power assigned to j) for binary[2]

    Though it works, looking at my explanation, it does seem complicated and reading the value as a String is an easier option.

    regards,
    Sudhir



     
    I agree. Here's the link: http://aspose.com/file-tools
     
    subject: Binary to Decimal conversion
     
    Similar Threads
    program assignment help
    Binary to decimal converter
    Convert decimal value to binary
    When does Java allow console input?
    passing values from one method to other