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.