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:
• Tim Cooke
• Campbell Ritchie
• Jeanne Boyarsky
• Ron McLeod
• Liutauras Vilda
Sheriffs:
• Rob Spoor
• Junilu Lacar
• paul wheaton
Saloon Keepers:
• Stephan van Hulst
• Tim Moores
• Tim Holloway
• Carey Brown
• Scott Selikoff
Bartenders:
• Piet Souris
• Jj Roberts
• fred rosenberger

# Convert decimal value to binary

Ranch Hand
Posts: 93
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
Your technique of an array, which you can print backwards, is a good way to display the results.

Ranch Hand
Posts: 287
• 1
• Number of slices to send:
Optional 'thank-you' note:
one line code

Campbell Ritchie
Marshal
Posts: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
Ha! ha! very funny!

Sudhir Srinivasan
Ranch Hand
Posts: 93
• Number of slices to send:
Optional 'thank-you' note:

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
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:

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.

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

Bartender
Posts: 10780
71
• Number of slices to send:
Optional 'thank-you' note:

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
• Number of slices to send:
Optional 'thank-you' note:
and you are creating different StringBuilder objects in the loop.

Winston Gutkowski
Bartender
Posts: 10780
71
• Number of slices to send:
Optional 'thank-you' note:

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
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
You’re welcome

Sudhir Srinivasan
Ranch Hand
Posts: 93
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:
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
• Number of slices to send:
Optional 'thank-you' note:

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: 75836
361
• Number of slices to send:
Optional 'thank-you' note:

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
• Number of slices to send:
Optional 'thank-you' note:

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
• Number of slices to send:
Optional 'thank-you' note:

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: 22656
126
• Number of slices to send:
Optional 'thank-you' note:
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.