Search code examples
crecursionbit-manipulationshortfunction-definition

Outputting bit values for unsigned short (C)


I have a function that takes an unsigned short and displays the bit values for it. Currently it displays all but the leading 0's, and I would like to display all 16 bit places instead.

void display_result(unsigned short result)
{
     if(result >> 1)
     {
          display_result(result >> 1);
     }
     if(result & 1)
     {
          putc('1', stdout);
     }
     else
     {
          putc('0', stdout);
     }
     return;
}

Example input: 3
Desired output: 0000000000000011
Actual output: 11

My understanding of my code was that it essentially iterated through the bit values of result the way it would through an array, outputting based on the if statement, but that's not what actually seems to happen, which tells me that I'm missing something. Can someone throw some light on this? (Note: I have searched for this info before posting, but my search fu may be lacking).


Solution

  • You need a full 16 iterations, not just until there are no significant digits. Using your approach, you could add a depth parameter:

    #include <stdio.h>
    #include <limits.h>
        static void display_result_n_(unsigned short result, int n)
        {
             if(--n) { display_result_n_(result>>1,n); }
             if(result & 1) { putc('1', stdout); }
             else { putc('0', stdout); }
             return;
        }
    
    void display_result(unsigned short result)
    {
        display_result_n_(result,sizeof(unsigned short)*CHAR_BIT);
    }
    int main()
    {
        display_result(3);
        puts("");
    }
    

    Or you could do it iteratively. For bases-of-two radixes, you don't need reversions (done for you by the recursion) if you simply test from the other (most significant) side by sliding a 1<<15 mask 16 times.

    void display_result(unsigned short result)
    {
        unsigned mask = 1U<<((sizeof(unsigned short))*CHAR_BIT-1);
        for(;mask;mask>>=1) putc('0'+ !!(result&mask),stdout );
    }