Write a C program that counts the number of 1s in the binary representation of an unsigned integer value (4 bytes)

11,749

Solution 1

Your count variable is not initialized, so it could start from any value at random1. Always initialized your variables:

int count = 0;

Then when you print it, you print the wrong thing - a pointer to count rather than the count itself, and without a carriage return, so you get it all on a line: if the numbers were correct you'd get a single issue of "12345" or "11122234445".

printf("Count is now is %d\n", count);

I'd strongly suggest you turn on all warnings from your compiler - this would have warned you of an uninitialized variable and almost certainly of the difference between the %d and what was fed to it (and maybe too the fact you're missing includes for printf)


1 perversely, in some controlled development environment memory is zeroed and you'd see no bug. Then you would okay the program for production. The program would run in a performance optimized environment where memory zeroing isn't worth the trouble. And there the program would start consistently failing. Since you're beginning, you don't want to pick up bad habits.

Solution 2

There are problems in your code:

  • you should not read the number as a float, you loose precision for numbers larger than 23 bits.
  • count is uninitialized. Even just incrementing it has undefined behavior.
  • you should print the number of bits with printf("%d\n", count); after the end of the loop. You currently print the address of count with an invalid conversion specifier for this type.

Here is a corrected version:

#include <stdio.h>

int main(void) {
    unsigned int num;

    printf("Please enter an integer: ");
    if (scanf("%u", &num) == 1) {
        int count = 0;
        while (num > 0) {
            count += num & 1;
            num >>= 1;
        }
        printf("%d\n", count);
    } else {
        printf("Warning: this is not a valid integer\n");
    }
    return 0;
}

Notes:

Share:
11,749

Related videos on Youtube

Frankie_C
Author by

Frankie_C

Programmmer

Updated on June 04, 2022

Comments

  • Frankie_C
    Frankie_C almost 2 years

    I'm trying to write a C program that will count all of the number of 1s in any binary representation of an integer that the user chooses and inputs. Then I want to print the total number of 1s. But first, I have to check to make sure the inputed number is an integer. My code:

    #include <stdio.h>
    
    int main() {
        int num;
        int count;
        float input;
    
        printf("Please enter an integer: ");
        scanf("%f", &input);
    
        num = (int)input;
        if (num == input) {
            while (num > 0) {
                count += num & 1;
                num >>= 1;
                printf("%d", &count);
            }
        } else {
            printf("Warning: this is not a valid integer.");
        }
        return 0;
    }
    

    When I run the code, I'm able to enter my integer of choice, but then I'm getting an output that says: 134148802013414880201341488020, or something similar. I've only recently started coding with C, so I'm not sure what this means or where my code is going wrong.

    • chux - Reinstate Monica
      chux - Reinstate Monica over 6 years
      Suggest to use unsigned u; scanf("%u", &u); and then count the 1s in u.
    • chux - Reinstate Monica
      chux - Reinstate Monica over 6 years
      int count; ...printf("%d", &count); should generate a compiler warning. Save time vs posting on SO. Enable all compiler warnings to see code is attempting to print the address of count and not the value of count.
    • axiac
      axiac over 6 years
      @Frankie_C what is C++ in this code?
    • Gene
      Gene over 6 years
      %f is definitely wrong. Use %u as @chux said
    • Frankie_C
      Frankie_C over 6 years
      @axiac Sorry confused threads. I was supposed to correct another thread. Put back.
  • Admin
    Admin over 6 years
    You're right, I overlooked initializing my count. I also think my print statement should be outside of my while loop. Thanks!
  • Admin
    Admin over 6 years
    One quick question: decimal numbers shouldn't be accepted, I think, but when I test the code with a decimal like 7.6, I receive an output instead of my custom warning. Why is that?
  • Costantino Grana
    Costantino Grana over 6 years
    Well, if you want to mention "more sophisticated ways", is worth mentioning that all modern processors/compilers have some flavor of popcnt() which inevitably takes incredibly less than any other trick we can come up with. Check out en.wikipedia.org/wiki/Intrinsic_function
  • chqrlie
    chqrlie over 6 years
    @GarrettMcClure: 7.6 is parsed by scanf("%u" as the integer 7 followed by other characters (.6) which are left in the input stream. It is cumbersome to use scanf() to perform precise input validation.
  • chqrlie
    chqrlie over 6 years
    @CostantinoGrana: good point. I have heard that some sophisticated C compilers actually detect naive bit counting algorithms and produce optimal code with popcnt or equivalent opcodes. This would be the best approach to optimisation as it favors simplicity and portability at the source level.