When working to understand any algorithm, you step through it with pencil-and-paper validating each step of the code. Pick a small test case, such as 10 as your input, which you know has a binary representation of 1010 and step through the four-iterations understanding what is happening.
If you do so, you will find the following:
while (i <= num) /* find next power-of-two greater than num */
i *= 2;
and then it is reduced by a power-of-two to eliminate any leading zeros as output, e.g.
i /= 2; /* divide by two, 1st power-of-two less than num */
This ensures i is the next power-of-two less than num. Now look at the algorithm in the do .. while (i > 0); loop (rearranged and indented so it makes more sense):
do { /* loop until i <= 0 */
if (num >= i) { /* is num >= i? */
std::cout << '1'; /* if so, output character '1' */
num -= i; /* reduce num by i */
}
else /* otherwise */
std::cout << '0'; /* output '0' character if num < i */
i /= 2; /* divide i by 2 (integer division intentional) */
} while (i > 0);
The algorithm is simple.
- Iteration one - since
i is the next power-of-two less than num the conditional if (num >= i) will test true guaranteeing the first character output will be '1'. num is then reduced by i (in the case where num = 10;), i = 8 on the first iteration so num -= i; leaves num = 2. i is divided by 2 leaving i = 4.
- Iteration two - the conditional is false,
'0' is output and i is divided again by 2 leaving i = 2, so i = num = 2.
- Third iteration - the conditional tests true, the character
'1' is output, num is reduced to 0, i is reduced to 1, you loop again.
- Fourth iteration - the conditional is false,
'0' is output and i is reduced to zero exiting the loop.
The correct binary representation of 10 is output:
1010
If you refactor the code to eliminate the unnecessary else condition based on whether num >= 0, you simply handle the negative or zero case and return. That saves a complete level of indention throughout the code. Putting it altogether, you can rewrite the same code as:
#include <iostream>
int main()
{
int num, i = 1;
std::cout << "Please enter a number: ";
std::cin >> num;
if (num <= 0) {
std::cout << "0\n";
return 0;
}
while (i <= num) /* find next power-of-two greater than num */
i *= 2;
i /= 2; /* divide by two, 1st power-of-two less than num */
do { /* loop until i <= 0 */
if (num >= i) { /* is num >= i? */
std::cout << '1'; /* if so, output character '1' */
num -= i; /* reduce num by i */
}
else /* otherwise */
std::cout << '0'; /* output '0' character if num < i */
i /= 2; /* divide i by 2 (integer division intentional) */
} while (i > 0);
std::cout << '\n'; /* tidy up with newline */
}
(note: See Why is “using namespace std;” considered bad practice? -- learning good habits is much easier than breaking bad ones later....)
Example Use/Output
$ ./bin/binary_conversion
Please enter a number: 10
1010
or
$ ./bin/binary_conversion
Please enter a number: 126
1111110
or
$ ./bin/binary_conversion
Please enter a number: 170
10101010
The code works fine. Look things over and let me know if you have further questions.