-1

I wrote a code which is supposed to count how many active bits (1s) are in a binary number that it gets from the user, considering the input is a correct binary number.

every time the code supposed to run the scanf() in main() it just get stuck , it does not stops running, it just feels like its thinking indefinitly and does not give any error

this is the code i wrote which in this situation prints "Please enter a binaric number: " and then it will get stuck

#include <stdio.h>


void count_bits(long int UserNum){
    int cnt=0;
    while(UserNum>0)
    {
        if (UserNum%10==1)
        {
            cnt++;  
        }   
    }
    printf("there are %d active bits\n",cnt);
}


int main(){
    long int UserNum=0;

    printf("Please enter a binaric number: ");
    scanf("%ld" , &UserNum);
    count_bits(UserNum);
    
    return 1;
}

if i write the scanf() first like this it won't even print:

scanf("%ld" , &UserNum);
printf("Please enter a binaric number: ");

what am i doing wrong here?

edit: examples input: 1101100

output:there are 4 active bits

input: 0110100111

output:there are 6 active bits

basically count how many ones there are in the number

Roy Shiff
  • 63
  • 7
  • 1
    It is waiting for you to input the number. – Xatenev Oct 30 '20 at 10:14
  • How do you know your code is still running? – Andrew Henle Oct 30 '20 at 10:15
  • 5
    In your loop, `UserNum` does not change value, so the end condition is never met. – Weather Vane Oct 30 '20 at 10:15
  • 1
    You have an endless loop in `count_bits`. You should add `UserNum /= 10;` at the end of the `while` loop. – Bodo Oct 30 '20 at 10:16
  • @TomKarzes Thats not what is written in the question. The sentence in the end `if i write the scanf() first like this it won't even print:` indicates that OP is not aware that scanf is waiting for input. – Xatenev Oct 30 '20 at 10:17
  • 1
    Also you are counting bits, so you need `UserNum % 2` and `UserNum /= 2`. Tens are not relevant. – Weather Vane Oct 30 '20 at 10:17
  • 1
    @Xatenev Oh sorry, I see what you're saying. I had missed the second part of the post. – Tom Karzes Oct 30 '20 at 10:19
  • 1
    Each time you check ```usernum``` you should also update the value because in your case what is done it is checking infinitely the same number again and again, that's why you don't get an error as well. – Chris Costa Oct 30 '20 at 10:19
  • Could you please [edit] and show one or two examples of input and expected output? – Jabberwocky Oct 30 '20 at 10:31
  • How do you find out that the code stops in the `scanf` line? The function `scanf` will wait for your input which has to be terminated with the Enter/Return key. – Bodo Oct 30 '20 at 10:57
  • ok it works, i thought the problem was with the scanf but for some reason it fixed it even though the problem was before the function has been called – Roy Shiff Oct 30 '20 at 11:07

2 Answers2

1

As pointed out in multiple comments UserNum>0 stays always true, and thereforethe loop never stops.

But anyway, the count_bits function is wrong alltogether. Doing modulo 10 operations for counting bits is pointless.

You want this:

void count_bits(long int UserNum) {
  int cnt = 0;

  while (UserNum > 0)
  {
    if (UserNum % 2)  // if UserNum is odd, then bit no. 0 is 1
      cnt++;

    UserNum = UserNum / 2;  // division by 2 shifts bits to the right
  }

  printf("there are %d active bits\n", cnt);
}

As we are working on a bit level, it would be more idiomatic to use bit shift and bit mask operartions though:

void count_bits(long int UserNum) {
  int cnt = 0;

  while (UserNum > 0)
  {
    if (UserNum & 1)    // mask all bits but bit no. 0
      cnt++;

    UserNum = UserNum >> 1;   // shift bits to the right
  }
  printf("there are %d active bits\n", cnt);
}

There is still room for improvement though. Especially negative numbers won't work properly (I didn't test though, find out yourself).

There are more sophisticated methods for counting bits such as described here: How to count the number of set bits in a 32-bit integer?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
1

I assume you want to interpret the decimal number entered by the user as a binary number. Your code does not check if your input follows this convention. If you enter a number that contains digits other than 0 or 1, every digit that is not 1 will be interpreted as 0. (UserNum%10==1)

Because of this assumption I don't discuss the fact that you normally would have to test bits with UserNum % 2 or UserNum & 1. (If you want to know how to enter or print a binary number instead of a decimal number, ask a separate question.)

Note that you may easily run in overlow issues if you enter a number that has too many digits.


Main problem: You have an endless loop in function count_bits because you don't update UserNum.

You can change it like this:

void count_bits(long int UserNum){
    int cnt=0;
    while(UserNum>0)
    {
        if (UserNum%10==1)
        {
            cnt++;  
        }
        UserNum /= 10;
    }
    printf("there are %d active bits\n",cnt);
}

With this change the code works for me as expected.

Please enter a binaric number: 0110100111
there are 6 active bits

Example of a number that is too big. (I added a line printf("You entered %ld\n", UserNum);.)

Please enter a binaric number: 10110111011110111110
You entered 9223372036854775807
there are 0 active bits

If you swap the printf and scanf in main (with the endless loop in count_bits), the message "Please enter a binaric number: " is not printed because it does not contain a newline and the output is line-buffered by default. Apparently scanf leads to flushing the output.

If you change it to print a trailing newline like

printf("Please enter a binaric number:\n");

it should get printed before entering count_bits (with the endless loop).

Bodo
  • 9,287
  • 1
  • 13
  • 29