• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Convert decimal value to binary

 
Ranch Hand
Posts: 93
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Hi,

My program takes input from the user a decimal value & converts to the corresponding binary one by using the "comparison with descending powers of 2 and subtraction" method

Program



and its successful output



As you can see, the code is pretty lengthy and my question is:

Is there an alternative way to code this program, say,

using signed left / right-shift operator (i do not know much about this)

for int operands (in my case the decimal value to be shifted and the amount to shift it by i.e exponent of base 2) ,

to allow entering '1's' and '0's' in the corresponding positions.

I don't know if this is the right way. If yes, can anyone help to get me started?

thanks,
Sudhir
 
Marshal
Posts: 79152
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are correct. It is long-winded. It has all sorts of things I am not happy about. Where did you find that algorithm? That looks dreadfully complicated, and if you are using Math.pow(2, j), there is a risk of your getting 511.999999999999 instead of 512, which will give you a wrong result.
Algorithm:
  • Create empty String
  • While i > 2
  • Find i % 2.
  • Add that number to the left end of your String.
  • Divide i by 2 in integer arithmetic
  • End of while
  • Display your String.
  • Much better than the algorithm you had.

    Don’t use shifts, because they presume you are in binary, and that would mean changing binary to binary.
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Your technique of an array, which you can print backwards, is a good way to display the results.
     
    Ranch Hand
    Posts: 287
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    one line code
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Ha! ha! very funny!
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:
    Algorithm:

  • Create empty String
  • While i > 2
  • Find i % 2.
  • Add that number to the left end of your String.
  • Divide i by 2 in integer arithmetic
  • End of while
  • Display your String.
  • Much better than the algorithm you had.



    Thank you for the algorithm and your suggestions. The code below



    gives the following output

    Output 1:



    As per the method now adopted (division by 2 with remainder), checking on paper showed the following result

    On paper:

    2 )55 1
    ------
    2 )27 1
    ------
    2 )13 1
    ------
    2 )6 0
    ------
    2 )3 1
    ------
    2 )1 1
    ------
    0

    I've modified the expression i > 2 in the while loop to i > 0 to accommodate the last remainder '1' missing in the program output.

    The output now is

    Output 2:



    which matches the result on paper.

    While the new method has greatly simplified the program, a new problem arises. The result 111011 shown on paper & in output 2 would,

    on reverse checking,



    give decimal value 59 which is incorrect (should be 55). From the paper result, the remainders should be displayed bottom upwards (110111 correct) as opposed to being displayed top downwards (111011 incorrect).

    Any suggestions on how to incorporate the same into the program.

    thanks,
    Sudhir


     
    Rancher
    Posts: 1776
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Might be he should have thought of suggesting you to add to the right or reverse the String while displaying.

    Try this -

     
    John Jai
    Rancher
    Posts: 1776
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    One more you can remove all your imports - you did not make use of the io or util package. And you don't need to import the lang package.

     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Got it! As suggested by John, I've reversed the string. The modified code below



    with the correct output



    thanks,
    Sudhir
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Doesn’t that look so much better Well done.

    I would still prefer a StringBuilder to using the + operator on Strings.
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:I would still prefer a StringBuilder to using the + operator on Strings.




    I've modified the original code by using StringBuilder (instead of String)


    Modified Program


    and the resultant output



    While the construction of the StringBuilder object indeed does do away with using + on Strings, it does not give the correct output (returns 111011) when the correct output is 110111. Could the reason be

    given that the append() method of the StringBuilder object converts input data (of any datatype) to its String representation, thereby returning the characters (111011) in the sequence they are appended (as Strings are immutable). reverse() method, used in the above code, does not seem to reverse the character sequence to give the correct output. Is it because of the immutable nature? OR where have i gone wrong......

    The modified code does raise a few questions (benefits of using StringBuilder over Strings):

    a) Would StringBuilder be more appropriate for loops with long String values.
    b)+ operator on Strings would be apt for shorter Strings
    c) When StringBuilder object is constructed within a loop (as in the code above), is it constructed once or for every iteration. This would impact on its memory and run-time performance?
    d) Does the compiler implicitly convert Strings(with + operator) to the StringBuilder object when using Strings.

    Awaiting your response.

    many thanks,
    Sudhir
    P.S: Do excuse me for the one too many questions


     
    Bartender
    Posts: 10780
    71
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sudhir Srinivasan wrote:Awaiting your response...


    Don't overthink this. You've got all the basic components there; you just need to put them in the right order. (Big Hint: try it by hand, and work out when you do the 'reverse' bit).

    Winston
     
    John Jai
    Rancher
    Posts: 1776
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    and you are creating different StringBuilder objects in the loop.
     
    Winston Gutkowski
    Bartender
    Posts: 10780
    71
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    John Jai wrote:and you are creating different StringBuilder objects in the loop.


    And that's of course true too

    Winston
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Winston Gutkowski wrote:
    Don't overthink this. You've got all the basic components there; you just need to put them in the right order. (Big Hint: try it by hand, and work out when you do the 'reverse' bit).



    Yes, I've got them in the wrong order. I've set it right and the code



    now gives the correct output




    John Jai wrote:and you are creating different StringBuilder objects in the loop.



    I've put the StringBuilder object outside the loop to create only one instance (of the same) and invoke the append and reverse methods.

    Thank you Winston and John!

    regards,
    Sudhir
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    If you use the insert() method of StringBuilder, and use index 0 throughout, you can get the binary output without needing to reverse anything.
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:If you use the insert() method of StringBuilder, and use index 0 throughout, you can get the binary output without needing to reverse anything.



    Thank you Campbell. As always your suggestion(s) simplifies the code further and in this case indeed does away with the reverse() method, replacing append with insert() method.

    The method takes in two int arguments, one indicating the offset position (in this case 0) and the other converting the int to String (in our case, variable with remainder value of division). The characters (1's and 0's) are added to the String in the sequence as specified by the offset. This is similar to the String.valueOf(int i) method (without the offset).

    Sudhir
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You’re welcome
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:
    I would still prefer a StringBuilder to using the + operator on Strings.



    I've used a bytecode editor to generate the following java bytecode to try to undertand how (in)efficient my java source code is and its run-time impact. I'm attempting to compare and analyse the program performance i.e my initial code (String with+ operator) with the subsequently modified ones (constructing StringBuilder inside the while loop and finally outside the while loop).

    I don't know about bytecode so my understanding and analysis is rudimentary at best.

  • File 1 implicitly generates StringBuilder object, adds characters to the object and finally converts toString
  • In File 1, the object is constructed three times (lines 19-26, 38-46, 54-61)
  • Files 2 and 3 construct it two times (lines 19 & 41) and (lines 19 & 32) respectively
  • The frequency of object construction, appends and conversion toString is more in File 1 than in Files 2 and 3
  • Compilation of File 1 would be decidedly slower to Files 2 & 3


  • A more sophisticated explanation from you would help me understand better. Could you also suggest a link / article about bytecodes in this regard.

    thanks,
    Sudhir

    File 1 - TestDec2Bin.class (Strings using + operator)




    File 2 - ConvertDec2Bin.class (StringBuilder_inside loop)



    File 3 - ConvertDec2Bin.class (StringBuilder_outside loop)

     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    I don’t think anybody will post a better explanation than what you have just shown. You can see how much effort you have put into it: well done
    When you have ten minutes to spare, try this class:You can see how quickly the lines with a StringBuilder local variable are completed, and how much slower multiple += calls on a String are. You can time it with some System class methods.

    I tried that program; I could see the delay after “Stringbuilder without size”, but not after “Stringbuilder with size”, because it was so fast. But “Using +=” has been sitting running for over 10 minutes and not completed.
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:I don’t think anybody will post a better explanation than what you have just shown. You can see how much effort you have put into it: well done



    Thank you Campbell! It means so much to get this appreciation from an expert.


    Campbell Ritchie wrote:
    When you have ten minutes to spare, try this class:You can see how quickly the lines with a StringBuilder local variable are completed, and how much slower multiple += calls on a String are. You can time it with some System class methods.

    I tried that program; I could see the delay after “Stringbuilder without size”, but not after “Stringbuilder with size”, because it was so fast. But “Using +=” has been sitting running for over 10 minutes and not completed.



    I'll certainly do as suggested and get back to you once I'm ready with my response.

    regards,
    Sudhir
     
    Campbell Ritchie
    Marshal
    Posts: 79152
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sudhir Srinivasan wrote: . . . I'll certainly do as suggested and get back to you once I'm ready with my response.

    regards,
    Sudhir

    Don’t worry; it will complete in under a week
     
    Winston Gutkowski
    Bartender
    Posts: 10780
    71
    Hibernate Eclipse IDE Ubuntu
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Sudhir Srinivasan wrote:A more sophisticated explanation from you would help me understand better...


    I'm not sure how far analysing bytecode is going to help you, but don't let me stop you. Most knowledge is good knowledge.

    The simple fact is that StringBuilder is mutable and String is not. In the normal course of events (and certainly in the case of the '+' operator) that means that every iteration through the loop with Strings causes at least one new object to be created (and sometimes more), whereas appending to a StringBuilder can be done in place (unless, of course, a new array has to be allocated to fit the additional information).

    The problem is that the compiler is extremely good at optimizing (far better than you in a lot of cases) and may well actually change some of your 'String + String' code to use StringBuilder under the hood; so analysing the bytecode may not produce the results you expect.

    The fact is that optimization - although darn fun - is far less useful than you might think (I refer you to my quote below); and as you go further you may even find code written by experts that appears, on the surface, to have been deliberately de-optimized.

    This page may help to explain why.

    Winston
     
    Sudhir Srinivasan
    Ranch Hand
    Posts: 93
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:Don’t worry; it will complete in under a week



    I needed the time for reasons (submission of my java project) other than the one mentioned by you.

    As suggested, I've implemented the System class method nanoTime() to time the StringBuilder object without size, with size and using the + operator. For example, its implementation on the object without size



    On running the program - just as you had said - there is a slight delay after "Using StringBuilder without size" but "StringBuilder with size" is timed in the blink of an eye. So far as "+=" is concerned, I'm certainly not going to stick around for a week for program completion.

    Coming back to the "without size" and "with size" objects



    the length of the String "Campbell" in both cases is the same, well within the objects' default capacity of 16 elements. So, the "without size" object does not have an internal buffer overflow, requiring the capacity() method to accommodate the additional characters, to necessitate the slight delay? Why then the time difference between the two?

    Is my assumption right. Could you please explain.

    thanks,
    Sudhir
     
    Sheriff
    Posts: 22781
    131
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    If you set the size (capacity is a better word) large enough so that it can hold everything it needs to hold, the internal structure does not need to be modified. If you don't specify a capacity, the internal structure (a char[]) gets a default size of 16. If that size is exceeded it will increase exponentially; the new capacity will be the old capacity + 2 (don't ask me why). So after 16 you get 34, 70, 142, etc. This requires quite a bit of resizing. That's what's taking the extra time.

    The solution with += actually creates a new StringBuilder object for each addition. The line output += "Campbell"; is compiled into output = new StringBuilder(output).append("Campbell").toString();. That's creating a new StringBuilder object, resizing its char[], adding "Campbell", then creating a new String object with the new contents. It's not only slow, it also requires quite a bit more memory. I've run a test like this quite a while ago and the number of garbage collection cycles was a lot higher than the StringBuilder solution, even without a specified capacity.
     
    Don't get me started about those stupid light bulbs.
    reply
      Bookmark Topic Watch Topic
    • New Topic