1

I am searching for codes that converts decimal to binary and i stumbled upon this:

#include <iostream>

using namespace std;


int main()
{
    int num;
    cout << "Please enter a number: ";
    cin >> num;
   
    if (num > 0) {
      int i = 1;
      while (i <= num)
      i *= 2;
      i /= 2;

      do {
        if (num >= i) {
           cout << '1';
           num -= i;
        }
        else
           cout << '0';
        i /= 2;
      } while (i > 0);
      cout << "";
      
    }
    
    else
      cout << '0';
}

I can't seem understand the logic of this loop

 while (i <= num)
      i *= 2;
      i /= 2;

i tried to put cout in between the equations to see the process

 while (i <= num)
    cout << i;
    cout << "A";
      i *= 2;
    cout << i;
    cout << "B";
      i /= 2;
    cout << i;
    cout << "C";

but it results to 111111111111111111... and doesn't stop can someone please explain

A.K.H
  • 31
  • 3
  • 1
    the loop is this only: while (i <= num) i *= 2; you should use curly braces to enclose the statements that you want the loop to execute – mangusta Aug 28 '20 at 01:37
  • As frequently seen in these questions, this loop doesn't convert decimal to binary at all. It converts binary to printable binary, or rather it would if it was written correctly. The only decimal to binary conversion here occurs at `cin >> num;`. – user207421 Aug 28 '20 at 01:57
  • Take out a pencil and paper and start with and input of `10` for `num` and work though the 4-interation. It is simply converting to binary starting with `i` equal to the next power-of-two greater than `num`. – David C. Rankin Aug 28 '20 at 02:42
  • @MarquisofLorne - it is written correctly, the indention is just screwed up. – David C. Rankin Aug 28 '20 at 02:44
  • @DavidC.Rankin Thank you, agreed. But it doesn't convert decimal to binary. – user207421 Aug 28 '20 at 03:43
  • I get that distinction -- though I suspect it is lost on the OP. What is wanted is a binary representation of the decimal number. The computer only knows binary, so the number is already binary, but to display that representation is generally the aim. The code just outputs characters of `'0's` and `'1's` based on an algorithm -- is one way to look at it. Looping and shifting a outputting based on the bit value is another. Both just means to the learnings end. – David C. Rankin Aug 28 '20 at 03:48
  • @DavidC.Rankin I think somebody must be teaching it this way judging by the frequency it appears here. I wish they'd stop. – user207421 Aug 28 '20 at 04:08
  • Agreed. And if you think about it. It is something everybody new to programming ultimately struggles through at one time or the other. "How do I look at what the bits are in memory?" So there are generally a number of variations on this same theme time time of the year (semester `:)` – David C. Rankin Aug 28 '20 at 04:25

2 Answers2

1

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.

  1. 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.
  2. Iteration two - the conditional is false, '0' is output and i is divided again by 2 leaving i = 2, so i = num = 2.
  3. Third iteration - the conditional tests true, the character '1' is output, num is reduced to 0, i is reduced to 1, you loop again.
  4. 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.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
-1

C++ is not Python, indentation and format literally has no effect.

 while (i <= num)
      i *= 2;
      i /= 2;

equals to

 while (i <= num)
 {
      i *= 2;
 }
 i /= 2;

That is, if while is not followed by a compound statement (i.e. statement block, surrounded by a pair of {}), then the loop body is only the first statement following while.

Latest version of commonly used compilers should have reported a warning about misleading indentation, it is a good habit to read every warning carefully.

LIU Qingyuan
  • 524
  • 5
  • 18
  • No. The OP's code is correct. It wouldn't make the slightest bit of sense to put the `i /=2;` inside the loop. The loop would do nothing and never terminate. NB Latest version of what commonly-used compilers? Why should a C++ compiler care about indentation in any way? – user207421 Aug 28 '20 at 03:43
  • Strange enough to see someone who didn't even read my answer to judge it. I have NEVER say the code is incorrect, it is just misleading, and you can see it confuses the question asker. – LIU Qingyuan Aug 28 '20 at 08:09
  • According to what presented in the question, the asker has little idea about C-style syntax and it impedes him to understand that code, so I point it out and hope it will help. Asker is not finding the fix of this code, but asking why and how it works. – LIU Qingyuan Aug 28 '20 at 08:16
  • "Why should a C++ compiler care about indentation in any way?" Don't ask me, ask the developers of Clang and GCC instead please @MarquisofLorne – LIU Qingyuan Aug 28 '20 at 08:17
  • I read it all right mate. Your 'answer', which isn't an answer, corrects a non-existent problem with indentation. – user207421 Aug 29 '20 at 05:15