Search

3.7 — Converting between binary and decimal

In order to understand the bit manipulation operators, it is first necessary to understand how integers are represented in binary. We talked a little bit about this in section 2.4 -- Integers, and will expand upon it here.

Consider a normal decimal number, such as 5623. We intuitively understand that these digits mean (5 * 1000) + (6 * 100) + (2 * 10) + (3 * 1). Because there are 10 decimal numbers, the value of each digit increases by a factor of 10.

Binary numbers work the same way, except because there are only 2 binary digits (0 and 1), the value of each digit increases by a factor of 2. Just like commas are often used to make a large decimal number easy to read (e.g. 1,427,435), we often write binary numbers in groups of 4 bits to make them easier to read (e.g. 1101 0101).

As a reminder, in binary, we count from 0 to 15 like this:

Decimal Value Binary Value
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111

Converting binary to decimal

In the following examples, we assume that we’re dealing with unsigned integers.

Consider the 8 bit (1 byte) binary number 0101 1110. 0101 1110 means (0 * 128) + (1 * 64) + (0 * 32) + (1 * 16) + (1 * 8) + (1 * 4) + (1 * 2) + (0 * 1). If we sum up all of these parts, we get the decimal number 64 + 16 + 8 + 4 + 2 = 94.

Here is the same process in table format. We multiply each binary digit by its digit value (determined by its position). Summing up all these values gives us the total.

Converting 0101 1110 to decimal:

Binary digit 0   1   0   1   1   1   1   0  
* Digit value

128 64 32 16 8 4 2 1
= Total (94)

0 64 0 16 8 4 2 0

Let’s convert 1001 0111 to decimal:

Binary digit 1   0   0   1   0   1   1   1  
* Digit value

128 64 32 16 8 4 2 1
= Total (151)

128 0 0 16 0 4 2 1

1001 0111 binary = 151 in decimal.

This can easily be extended to 16 or 32 bit binary numbers simply by adding more columns. Note that it’s easiest to start on the right end, and work your way left, multiplying the digit value by 2 as you go.

Method 1 for converting decimal to binary

Converting from decimal to binary is a little more tricky, but still pretty straightforward. There are two good methods to do this.

The first method involves continually dividing by 2, and writing down the remainders. The binary number is constructed at the end from the remainders, from the bottom up.

Converting 148 from decimal to binary (using r to denote a remainder):

148 / 2 = 74 r0
74 / 2 = 37 r0
37 / 2 = 18 r1
18 / 2 = 9 r0
9 / 2 = 4 r1
4 / 2 = 2 r0
2 / 2 = 1 r0
1 / 2 = 0 r1

Writing all of the remainders from the bottom up: 1001 0100

148 decimal = 1001 0100 binary.

You can verify this answer by converting the binary back to decimal:

(1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 148

Method 2 for converting decimal to binary

The second method involves working backwards to figure out what each of the bits must be. This method can be easier with small binary numbers.

Consider the decimal number 148 again. What’s the largest power of 2 that’s smaller than 148? 128, so we’ll start there.

Is 148 >= 128? Yes, so the 128 bit must be 1. 148 - 128 = 20, which means we need to find bits worth 20 more.
Is 20 >= 64? No, so the 64 bit must be 0.
Is 20 >= 32? No, so the 32 bit must be 0.
Is 20 >= 16? Yes, so the 16 bit must be 1. 20 - 16 = 4, which means we need to find bits worth 4 more.

Is 4 >= 8? No, so the 8 bit must be 0.
Is 4 >= 4? Yes, so the 4 bit must be 1. 4 - 4 = 0, which means all the rest of the bits must be 0.

148 = (1 * 128) + (0 * 64) + (0 * 32) + (1 * 16) + (0 * 8) + (1 * 4) + (0 * 2) + (0 * 1) = 1001 0100

In table format:

Binary number 1   0   0   1   0   1   0   0  
* Digit value

128 64 32 16 8 4 2 1
= Total (148)

128 0 0 16 0 4 0 0

Another example

Let’s convert 117 to binary using method 1:

117 / 2 = 58 r1
58 / 2 = 29 r0
29 / 2 = 14 r1
14 / 2 = 7 r0
7 / 2 = 3 r1
3 / 2 = 1 r1
1 / 2 = 0 r1

Constructing the number from the remainders from the bottom up, 117 = 111 0101 binary

And using method 2:

The largest power of 2 less than 117 is 64.

Is 117 >= 64? Yes, so the 64 bit must be 1. 117 - 64 = 53.
Is 53 >= 32? Yes, so the 32 bit must be 1. 53 - 32 = 21.
Is 21 >= 16? Yes, so the 16 bit must be 1. 21 - 16 = 5.

Is 5 >= 8? No, so the 8 bit must be 0.
Is 5 >= 4? Yes, so the 4 bit must be 1. 5 - 4 = 1.
Is 1 >= 2? No, so the 2 bit must be 0.
Is 1 >= 1? Yes, so the 1 bit must be 1.

117 decimal = 111 0101 binary.

Adding in binary

In some cases (we’ll see one in just a moment), it’s useful to be able to add two binary numbers. Adding binary numbers is surprisingly easy (maybe even easier than adding decimal numbers), although it may seem odd at first because you’re not used to it.

Consider two small binary numbers:
0110 (6 in decimal) +
0111 (7 in decimal)

Let’s add these. First, line them up, as we have above. Then, starting from the right and working left, we add each column of digits, just like we do in a decimal number. However, because a binary digit can only be a 0 or a 1, there are only 4 possibilities:

  • 0 + 0 = 0
  • 0 + 1 = 1
  • 1 + 0 = 1
  • 1 + 1 = 0, carry a 1 over to the next column

Let’s do the first column:

0110 (6 in decimal) +
0111 (7 in decimal)
----
   1

0 + 1 = 1. Easy.

Second column:

 1
0110 (6 in decimal) +
0111 (7 in decimal)
----
  01

1 + 1 = 0, with a carried one into the next column

Third column:

11
0110 (6 in decimal) +
0111 (7 in decimal)
----
 101

This one is a little trickier. Normally, 1 + 1 = 0, with a carried one into the next column. However, we already have a 1 carried from the previous column, so we need to add 1. Thus, we end up with a 1 in this column, with a 1 carried over to the next column

Last column:

11
0110 (6 in decimal) +
0111 (7 in decimal)
----
1101

0 + 0 = 0, but there’s a carried 1, so we add 1. 1101 = 13 in decimal.

Now, how do we add 1 to any given binary number (such as 1011 0011)? The same as above, only the bottom number is binary 1.

       1  (carry column)
1011 0011 (original binary number)
0000 0001 (1 in binary)
---------
1011 0100

Signed numbers and two’s complement

In the above examples, we’ve dealt solely with unsigned integers. In this section, we’ll take a look at how signed numbers (which can be negative) are dealt with.

Signed integers are typically stored using a method known as two’s complement. In two’s complement, the leftmost (most significant) bit is used as the sign bit. A 0 sign bit means the number is positive, and a 1 sign bit means the number is negative.

Positive signed numbers are stored just like positive unsigned numbers (with the sign bit set to 0).

Negative signed numbers are stored as the inverse of the positive number, plus 1.

Converting integers to binary two’s complement

For example, here’s how we convert -5 to binary two’s complement:

First we figure out the binary representation for 5: 0000 0101
Then we invert all of the bits: 1111 1010
Then we add 1: 1111 1011

Converting -76 to binary:

Positive 76 in binary: 0100 1100
Invert all the bits: 1011 0011
Add 1: 1011 0100

Why do we add 1? Consider the number 0. If a negative value was simply represented as the inverse of the positive number, 0 would have two representations: 0000 0000 (positive zero) and 1111 1111 (negative zero). By adding 1, 1111 1111 intentionally overflows and becomes 0000 0000. This prevents 0 from having two representations, and simplifies some of the internal logic needed to do arithmetic with negative numbers.

Converting binary two’s complement to integers

To convert a two’s complement binary number back into decimal, first look at the sign bit.

If the sign bit is 0, just convert the number as shown for unsigned numbers above.

If the sign bit is 1, then we invert the bits, add 1, then convert to decimal, then make that decimal number negative (because the sign bit was originally negative).

For example, to convert 1001 1110 from two’s complement into a decimal number:
Given: 1001 1110
Invert the bits: 0110 0001
Add 1: 0110 0010
Convert to decimal: (0 * 128) + (1 * 64) + (1 * 32) + (0 * 16) + (0 * 8) + (0 * 4) + (1 * 2) + (0 * 1) = 64 + 32 + 2 = 98
Since the original sign bit was negative, the final value is -98.

If adding in binary is difficult for you, you can convert to decimal first, and then add 1.

Why types matter

Consider the binary value 1011 0100. What value does this represent? You’d probably say 180, and if this were standard unsigned binary number, you’d be right.

However, if this value was stored using two’s complement, it would be -76.

And if the value were encoded some other way, it could be something else entirely.

So how does C++ know whether to print a variable containing binary 1011 0100 as 180 or -76?

Way back in section 2.1 -- Basic addressing and variable declaration, we said, “When you assign a value to a data type, the compiler and CPU takes care of the details of encoding your value into the appropriate sequence of bits for that data type. When you ask for your value back, your number is “reconstituted” from the sequence of bits in memory.”

So the answer is: it uses the type of the variable to convert the underlying binary representation back into the expected form. So if the variable type was an unsigned integer, it would know that 1011 0100 was standard binary, and should be printed as 180. If the variable was a signed integer, it would know that 1011 0100 was encoded using two’s complement (assuming that’s what it was using), and should be printed as -76.

What about converting floating point numbers from/to binary?

How floating point numbers get converted from/to binary is quite a bit more complicated, and not something you’re likely to ever need to know. However, if you’re curious, see this site, which does a good job of explaining the topic in detail.

Quiz

1) Convert 0100 1101 to decimal.
2) Convert 93 to an 8-bit unsigned binary number.
3) Convert -93 to an 8-bit signed binary number (using two’s complement).
4) Convert 1010 0010 to an unsigned decimal number.
5) Convert 1010 0010 to a signed decimal number (assume two’s complement).

6) Write a program that asks the user to input a number between 0 and 255. Print this number as an 8-bit binary number (of the form #### ####). Don’t use any bitwise operators.

Hint: Use method 2. Assume the largest power of 2 is 128.
Hint: Write a function to test whether your input number is greater than some power of 2. If so, print ‘1’ and return your number minus the power of 2.

Quiz answers

1) Show Solution

2) Show Solution

3) Show Solution

4) Show Solution

5) Show Solution

6) Show Solution

3.8 -- Bitwise operators
Index
3.6 -- Logical operators

323 comments to 3.7 — Converting between binary and decimal

  • Arumikaze

    Hello! Thank you for answering my previous question a few lessons back. I am back with another question. I have done the last question and I was wondering if the way I did it is optimal. My answer seems to be different from the answer provided, but I assume that is partially because we haven't covered loops yet. If you can please give me feedback on my code, I would greatly appreciate it. Thank you so much!

    • Hi Arumikaze!

      * Line 14, 15, 26: Use /= and -= operators
      * Line 43: Initialize to 0
      * Line 16, 17 and 27, 28: Can be reduced to

      * Line 15-21 and 26-32 are identical, don't repeat yourself, move the code outside of the conditional block.
      * You could've modified @input without creating a copy

  • Stewert

    The program prints the results in reverse order: it prints 76 decimal = 00110010, instead of 01001100.

  • Stewert

    Using the first method I did the following:
    (is there an easy way to flip the results?)

    #include <iostream>

    int decimalToBinary(int x){
        
        int y;
        if (x%2){y = x/2; std::cout<<"1";}
        else {y = x/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1";}
        else {y = y/2; std::cout<<"0";}
        if (y%2){y = y/2; std::cout<<"1"<<endl;;}
        else {y = y/2; std::cout<<"0"<<endl;;}
        }

    int main(){
    cout << "enter a number: "<<endl;
    int x;
    cin>>x;

    decimalToBinary(x);
        

        system("pause");
        return 0;
    }

    • Hi Stewart!

      * Don't use "using namespace"
      * Initialize your variables with uniform initialization
      * You're executing (y/2) no matter what, move it outside of the conditional blocks
      * Don't use @std::system unless you have to. If you have to, use @std::system rather than @system

      What do you mean by "flip the results"?

  • Marcos

    Should there be a preference placed on repetitive function calls or stepping if statements in terms of performance? I used literals for the power values in my binary conversion function which I expect reduced the re-usability but allows a single function call to handle the entire conversion instead of returning to main then back to convert and repeat.

    • nascardriver

      Hi Marcos!

      Don't repeat yourself https://en.wikipedia.org/wiki/Don%27t_repeat_yourself

      If you're writing almost identical code over and over again, wrap it in a function (or use a loop).

      • Marcos

        My question more pertains to the scope shifting, thank you for reminding me to wrap repetitive code in a loop though. In the example he calls the secondary function for each pow value which I presume causes the program to shift focus to the other function, operate, return, then repeat, is that preferable to having a loop within the secondary function? Is it better to loop a function call that performs a single action or have a single function call that loops an action?

        • nascardriver

          Function calls have a small performance cost, but don't let that distract you. If your compiler thinks the program will be better without the call it will copy the function's contents to the caller. Loops haven't been covered yet, that's why I put them in braces. If they were, then you should use them here, but since they haven't, you should do it as Alex did in his solution.

  • Kazutadashi

    Similar method using the '?' operator:

    • nascardriver

      Hi Kazutadashi!

      * Don't use "using namespace".
      * Use uniform initialization.
      * Although the conditional operator makes the code look simpler, it requires you to perform each check twice, which is bad.
      * Wrap the check and print in a function, repeated code is bad.

      • nascardriver

        They can cause name collisions, you'll learn more about this in lesson 4.3c.

      • Kazutadashi

        What's the reasoning behind not using "using namespace"?

        I think I have fixed most of the issues here:

        Thank you for your help!

        • nascardriver

          Initialize @x in line 7, std::cin.operator>> is only guaranteed to override the variable in C++11 or later.
          You don't need -= in line 19, - is enough since you're not using @decimalNumber after that line.
          Just return @decimalNumber in line 24.
          You're using the same name style for functions and variables, this can lead to confusion, change it before you get used to it.
          You're code is better than Alex' solution already, because you're only performing one check in @convertToBinaryAndPrint, keep it up!

          • Alex

            I added a bit about compound statements to the introductory lesson on if-statements, which means I can now use it here as part of the official solution to remove the redundancy. Quiz solution updated.

            Thanks for reminding me that I'd meant to do that.

  • Reynaldo

    Hi! Thanks for these tutorials, they're awesome. I'd love to know how I can improve my code for #6 and I might have jumped ahead using looping sorry!

    • nascardriver

      Hi Reynaldo!

      * Use @std::pow instead of @pow. It's the same function, but @<cmath> isn't required to declare @pow in the global namespace.
      * Line 37: Initialize @userInput to 0 so the reader doesn't need to know what C++ defaults to.
      * @binaryConverter: Lines 21-23 are equivalent to lines 27-29, move those outside the if-else block.

      Everything else looks fine, good job!

  • ArmaIG

    Hi Teacher, for exercise 6 I came up with a very similar code as shown in the answer, the difference is that I tried the next for my bit printer function which I called convertDecBin:

    It worked fine, but is there any risk when using this conditional instead of if in this case?
    Also, using unsigned int is correct or is it better to use only int?

    • Alex

      It's fine to use the conditional operator here.

      It's generally better to use int than unsigned int, unless you're doing bit-level manipulation (e.g. using bit flags, which we talk about shortly)

  • Quamruz Zaman

    Hi Alex,
        From Chapter 2.8 Literals, i learned that from c++14 onwards we can assign binary literals by 0b prefix.
       So, i tried the same, but when i tried to print the output on the console for both signed as well as unsigned int, it outputs the same value in decimal, whereas as per this line from this chapter “When you assign a value to a data type, the compiler and CPU takes care of the details of encoding your value into the appropriate sequence of bits for that data type. When you ask for your value back, your number is “reconstituted” from the sequence of bits in memory.” it should have output 180 for unsigned int and -76 for signed int for binary value 1011 0100, but in both the cases it outputs 180.
       Can you please explain the reason for the output?

        Here is my code:

    • nascardriver

      Hi Quamruz!

      You supplied 8bit numbers, an (unsigned) int is most likely 32bits on your system.

      These obviously aren't the numbers you expected either, but they are positive and negative.
      I don't think the standard requires a specific system for storing negative integers, so you might get different results with different compilers, I'll leave figuring this out up to you.

  • FelixPhill

    Hi! I've been working on this program but I can't get it to terminate if x < 0 && x > 255. I thought the return 0 in func() would terminate it but it still goes through back to main.

  • david s

    After working on my code for over a week to solve question 6 and not being able to get it to work, I finally looked at the solution and saw how simple your code was.  I have been having trouble understanding functions when they get a little complicated such as my function below... calcUserNumber().  I wrote the code this way hoping to grasp a better understanding of functions--I think I'm close but I'm stuck.
    I'm hoping someone can help with the code I have written.  
    Thank you!

    I used std::cout towards the bottom of main() to see what was in the variables...

    • nascardriver

      Hi David!

      What you need are references

      Also, enable compiler warnings and fix them.

      References
      * Lesson 7.3 - Passing arguments by reference

  • Harsh Verma

    What is the use of binary in the modern times

    • Alex

      In many cases it's not all that important. It's mainly useful when dealing with manipulating individual bits, which you may or may not ever have cause to do.

  • Dan

    Maybe I went a little more overboard on this than I needed to but it was fun to do and I learned a lot! I have to admit, when I got to this lesson, I almost just skipped over it, not really caring that much but then I realized its pretty important to understand this conversion process so decided to dive in. I had a lot of fun trying to make a solution, and I did it quite differently than what you have. it did take me googling a few things (like string append and setf for removing scientific notation on numbers), but at the end from my tests it works really well.

    I'd love some input and if you feel there was a better way to accomplish what I did. I added some notes where it seemed appropriate. I also started before coding by doing notes at the top on how the program should work, and I kept "breaking it down" as described in earlier lessons.

    Thanks!

    • nascardriver

      Hi Dan!

      Good job solving the quiz! Doing more than what the quiz asked for is great to learn more about to language.

      Suggestions:
      * You're using a long double, but you're neither using floating points nor the big range of a long double. An int is enough, the long double just adds extra work.
      * Initialize your variables with uniform initialization
      * You're using the same naming convention for variables and functions, this can lead to confusion.
      * If your 'default' case is empty you might as well omit it.
      * Line 84: Use a regular if-statement unless you need the return value of the conditional operator.

      Notes:
      * You can use @std::string::operator+= to append text, there's nothing wrong with using @std::string::append

  • Isaiah D Frazier

    //This looks a lot messier than you solution, but is there anything wrong with it besides the look?

    #include "stdafx.h"
    #include <iostream>

    int checkBinary(int x)
    {
        {
            int bianry = (x > 128) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 128;
            }
        }
        {
            int bianry = (x < 128 && x >= 64) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 64;
            }
        }
        {
            int bianry = (x < 64 && x >= 32) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 32;
            }
        }
        {
            int bianry = (x < 32 && x >= 16) ? 1 : 0;
            std::cout << bianry << " ";
            if (bianry == 1)
            {
                x -= 16;
            }
        }
        {
            int bianry = (x < 16 && x >= 8) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 8;
            }
        }
        {
            int bianry = (x < 8 && x >= 4) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 4;
            }
        }
        {
            int bianry = (x < 4 && x >= 2) ? 1 : 0;
            std::cout << bianry;
            if (bianry == 1)
            {
                x -= 2;
            }
        }
        {
            int bianry = (x < 2 && x >= 1) ? 1 : 0;
            std::cout << bianry <<std::endl;
            if (bianry == 1)
            {
                x -= 1;
            }
        }
        return x;

    }
    int main()
    {
        std::cout << "Enter an Integer value between 1 and 255\n";
        int x;
        std::cin >> x;
        checkBinary(x);
        return 0;
    }

    • Isaiah D Frazier

      P.S I realize my spelling errors. My focus wasn't on spelling, just functionality.

    • nascardriver

      Hi Isaiah!

      * Don't repeat yourself. You have very similar code again and again, that's bad, that's what functions are for.
      * Initialize your variables with uniform initialization

  • Lucas

    super h4x0r 1337 lvl efficiency, im beste.

  • Musa

    Am I complicating things? Looking at your answer I guess I am. Any feed back is appreciated

  • J Gahr

    Would it be more performant to do this:

    and just hit Ctrl-v 8 times instead of having to manually enter 128, then 64, then 32, etc. like this:

    • nascardriver

      Hi J!

      Assuming compiler optimizations are disabled, this is slower than the manual solution, because your computer would need to divide pow 7 times whereas the manual solution doesn't involve any calculations.
      With compiler optimizations enabled the divisions will be executed at compile-time and the binary is equivalent.

  • J Gahr

    First off, thanks for all of these free awesome tutorials.

    Here is my solution Problem 6.

    1) Are there any bad habits expressed within my program of which I should be wary? (For instance, Akash Patel's solution (below mine) does not use magic numbers, which I like.)

    2) Off-topic question: Have the previous lessons given a way to account for the user entering a letter or symbol instead of a number?

    • nascardriver

      Hi J!

      Akash used content from future lessons which allowed him to have shorter code.
      I'm surprised by how well written your code is, this doesn't happen often. The only thing I'd change is that you're using a double throughout your calculations. Your CPU is better at dealing with integers than floating point values. I understand why you initially store the value in a double and casting types hasn't been covered yet so this is nothing you could've done anything about.

      EDIT:
      Actually, there is a problem and your compiler should've warned you about it.

      What's happening?

      Prints 1/0 depending on the boolean value. The << operator then returns the stream object so what you're left with is

      and this statement doesn't have an effect.

  • Akash Patel

    This seems to work

    • nascardriver

      Hi Akash!

      Congratulations on solving the quiz! I made some changes to your code and added comments:

  • Tony

    Alex, I don't get some examples.

    You wrote:
    "In two’s complement, the leftmost (most significant) bit is used as the sign bit"

    But in the examples, what I've seen is that you change the rightmost bit(you add 1 to the rightmost), not the leftmost:

    Can you please explain it? :S

    • Alex

      Yes, we're talking about two different things.

      The sign bit is used to control the sign of the number -- in other words, whether it is positive or negative. With a signed number, using twos complement, numbers that have a leftmost bit of 0 are considered positive, and numbers that have a leftmost bit of 1 are considered negative.

      For example, 0000 0100 = 4, 1111 1100 = -4.

      This is independent of how we add 1 to a number.

  • Peter Baum

    Third paragraph - you might want to change
    " there are only 2 binary numbers"
    to read
    " there are only 2 binary digits"

  • Matt

    Good evening!

    I have a couple questions - some are recurring and I'm finally getting around to ask them, and some are specific to the quiz in this lesson.

    1: Quite often we are asking the user for a console input and assigning their input to a variable. Which of these should I use for this type of task? I've reviewed prior lessons discussing initialization and the concept must just not be clicking. I want to squash this point of confusion while I'm still early in learning.

    1a. Copy Initialization

    1b. Direct Initialization

    1c. Uniform Initialization

    2. At least twice now (once when writing the program to calculate a ball being dropped from a tower and now for this program to convert a decimal value to binary) the programs in the solutions to the quiz have had int main() call a function that performs two actions. I thought this was a hard "no-no" which really threw me for a loop (pun intended) when I was brainstorming my own solutions to the quizzes. For example, in this lesson's quiz, the following was my original "outline" before I decided it wasn't going to work, or that I didn't know how to make it work:

    Essentially I was going to try to send the input to the convert() function, write the binary number in decimal format (eg: convert 200 to 11001000), return it back to int main() where it would be sent to the print() function to be written in the console. After struggling with this for a while, I decided to peak and see if I was on the right track where I was again surprised to see functions with 'and' in them performing multiple actions (math and printing, in this example).

    When is it ok to have a function that performs multiple tasks?

    After being nudged in the proper direction, I came up with this:

    3. If I'm writing a program such as the one above, is there really any need to use

    since I'm not using that variable anywhere else? It's being used exactly once, when it is passed as an argument in the

    function call. Is it just good habit?

    4. Lastly, how do I get 'n' to properly copy in code brackets here on this forum? As seen in my code above, the backslashes aren't displaying.

    • nascardriver

      Hi Matt!

      1:
      Uniform initialization whenever possible. Enable all warnings in your compiler and you'll get warnings when you try to initialize variables with types that would be casted.

      2:
      > When is it ok to have a function that performs multiple tasks?
      Whenever the tasks are strongly related to each other and you don't need the results of the called function outside of the wrapper.

      The commenting system messed up your code (@Alex pls fix), from what I can tell it looks good, it could be improved with content covered in upcoming lessons.

      > Is this std::endl; necessary here? What happens if our program finishes with a n?
      Use std::endl whenever you don't need high-speed bulk text output. std::endl will make sure your text gets printed right away while \n might wait a little longer.

      3:
      > is there really any need to use
      No there's not. const is generally only used for references and pointers (Covered in later lessons). You can use it for 'normal' variables like you did but other than having the compiler remind you that you're trying to write to a variable you marked as read only there are no benefits.

      4:
      I'll leave this one for @Alex, it appears to work for some people and for others it doesn't (Especially when using the edit function).

      Don't hesitate to ask questions, that's what the comment section is for.

      • Alex

        I'm aware that the commenting system has a few glitches, as there are 3 commenting-related plugins installed that don't quite play nice with each other. I'll reassess whether the site can live without one of the three (or whether there are newer plugins that perform the same functions without the side-effects).

  • wayne

    Hi Alex,

    Thank you for this wonderful tutorial series. You are very generous in sharing your time, energy and expertise. I would like to share my answer to question 6. I tried to incorporate as much as what I could from the previous sections. I also read ahead and incorporated a while loop. My program appears to work. I would appreciate any comments regarding good programming practice or areas where I could improve it. Thanks in advance.

    in file conversion.h

    #ifndef CONVERSION_H
    #define CONVERSION_H

    int getUserInput();
    void convertDecimalToBinary(int, int, int *);
    void printResult(int *);

    #endif

    in file conversion.cpp

    /*
    * This program asks the user to input an integer between 0 and 255, inclusive. The program then converts the number to base 2 and
    * displays the result as an 8 bit binary number using the following format: #### ####
    */
    #include <iostream>
    #include "conversion.h"

    int getUserInput()
    {
       std::cout << "Enter an integer between 0 and 255, inclusive: ";
       int userInput;
       std::cin >> userInput;
       return userInput;
    }

    void convertDecimalToBinary(int numBase_10, int powerOf_2, int *ptr)
    /*
    * To convert to binary we will examine numBase_10 to see if it's greater than or equal to the given powerOf_2.
    * If numBase_10 is greater than or equal to the given powerOf_2 then the corresponding bit must be a "1" else it is a "0."
    * If numBase_10 is greater than or equal to the given powerOf_2 that we must subtract that power of 2 to get the value that must
    * still be accounted for by the remaining bits; this will decrease numBase_10 until it is 0.
    */
    {
       while(powerOf_2 >= 1)
       {
          int bit = (numBase_10 >= powerOf_2) ? 1 : 0;
          numBase_10 = (numBase_10 >= powerOf_2) ? (numBase_10 - powerOf_2) : numBase_10;        // This will give the remaining value.
          powerOf_2 = powerOf_2 / 2;  // This will perform integer division and assign the next power of 2 to powerOf_2 (i.e. 128, 64, 32...
          *ptr = bit;
          ++ptr;
       }
    }

    void printResult(int *ptr)
    {
       int index{0};     // index is used to step through our array, which has 8 elements.
       while(index < 8)
       {
          if(index != 4)
             std::cout << *ptr;
          else
             std::cout << " " << *ptr;
          ++index;
          ++ptr;
       }
       std::cout << std::endl;
    }

    in file main.cpp

    /*
    * This program asks the user to input an integer between 0 and 255, inclusive. The program then converts the number to base 2 and
    * displays the result as an 8 bit binary number using the following format: #### ####
    */
    #include <iostream>
    #include "conversion.h"

    int main()
    {
       int numBase_10 = getUserInput();
       int powerOf_2{0x80};                 // 0x80 is 128 in hexadecimal, which is the largest "power of 2" in an 8-bit byte.                  
       int *ptr, outputBits[8];
       ptr = &outputBits[0];
       convertDecimalToBinary(numBase_10, powerOf_2, ptr);
       printResult(ptr);
       return 0;
    }

    • Matias

      I think it works well but you may be overcomplicating this. I get it if you're trying to do so for like learning purposes but really I think you should stick to getting programs to be as efficient as possible. I'll try to provide input on what you have, and I'll share the code I came up with so that it's not just me telling you "Hey my way's right and yours is wrong" because I'm in no position (or knowledge) to do so. Anyways,

      1) For getUserInput(), you should at least verify that the number entered is in the desired range. There's the extra (and recommended step) which I didn't take either that is to verify that the input stream is not in a failed state, as well as to "remove" any of the trailing input after the integer that's read in. Here's how I would "replace" your getUserInput() function:

      2) The conversion function looks good, just one line where you could've shortened it up a bit:

      3) For the print function, I'd write it like this since the line to print the dereferenced ptr is shared on both (assuming you want to split it after the 4th bit, which I guess is your intent). This should make it more compact and a bit more readable (at least imo):

      Other than that it looks good ! I am getting back into stuff too so there's a chance that I didn't pick on some other things that you could improve, or even worse, made mistakes myself. I tried to double check my answer as the most I could, so I apologize if I misled you in any way.

      Good luck with future coding endeavors =)

      Here's the fixed version of how my code looked:

      • wayne

        Thanks, Matias, for your comments and recommendations. I can definitely see the wisdom in checking to see if the input is in the desired range. I still have a lot more reading (and learning) to do. Your code seems very sophisticated!

        Thanks again,

        • Matias

          If there's something I don't have it's definitely wisdom lol. I've been programming off and on for about 6 years now (I'm 20 now, and I started playing around with programming when I was 14). If there's one solid piece of advice I can give you it's this: take it easy, and enjoy what you do. Don't try to push these lessons to be "over as fast as they can" because there's a lot of good content in them. Also, try to find applications of each lesson and try to come up with problems to solve with code yourself, and do tiny programs that you can improve/grow in size as you progress across the tutorials. Also, don't be afraid of checking back on sections, there's no shame in revisiting a concept, specially in a language like c++!

          Also for next time, if you want to put code, use "

          " tags, or you can put a Pastebin/Ideone link to your source code.

          Good luck !

    • Alex

      In general, your coding style is great -- lots of comments, well named variables, correct use of multiple files and function prototypes in a header, etc... Good work! A few nitpicks:
      1) getUserInput() should probably be in main.cpp, not conversion.cpp.
      2) in main(), powerOf_2 should be const.
      3) You don't need the variable int *ptr. Just pass outputBits, and the fixed array will decay into a pointer:

  • Matias

    Here's my solution to the last problem, I think there's a couple of concepts that are not familiar in the series so far, but perhaps someone can make good use of this.

    Thanks for the tutorials, love them !

    ( I realize I could've added a print8BitBinary function but oh well, I guess I play into the lazy programmer stereotype :p)

    • Matias

      There was a tiny error in the conversion method, where i was starting to evaluate at 2^8 instead of 2^7. oopsie.

      Here's the fixed version of the code above, with the print function.

  • Happilicious

    Dear Alex, I think on "Converting integers to binary two’s complement" section, it can be better by showing examples from negative values to positive with step by step guide, as you just showed only positive to negative conversion. I ended up confused on "Converting binary two’s complement to integers" section, which converts negative to positive via positive to negative method. It would be easier to read in my opinion.

    Thank you.

  • Jim

    "pow" is much more powerful and efficient than eight "if/then" statements!! But I also learned some more about displaying current values in finding my ererz... DUH!!!

    The main difference in my code was a test for out of range input. WOW! :blush:

  • Robert W

    Here is a way you can write the program, using a for loop:

  • Sooi Shanghei

    Suggestion: this page could use a summary

  • Dennis

    Hey, why do you use 2 if statements here:

    ?

    Isn't that just inefficient and not so nice code?

    looks much nicer to me.

    • Alex

      Yes, I agree, but I hadn't covered blocks at this point in the tutorials.

      • Matt

        Ah! I knew something like this had to be possible.  So far, every time I've thought to myself, "Self, there must be an easier way to do this thing I'm trying to do," I've been right.  Then, a lesson or two later you show me what that easier way is.  This tutorial series has been incredible.

  • Jup

    This seems to work for me. What do you think about it? 🙂

Leave a Comment

Put all code inside code tags: [code]your code here[/code]