Outputting bit values for unsigned short (C)

76 Views Asked by At

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).

2

There are 2 best solutions below

0
On BEST ANSWER

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 );
}
4
On

The recursive function needs to know how many times it must be recursively called. That is it needs somehow to know the size of an object of the type unsigned short.

In general there are two approaches.

The first one is two write two functions. The first one will have at least one parameter, the number, and the second one will have at least two parameters, the number and the current bit position.

Here is a demonstrative program.

#include <stdio.h>
#include <limits.h>

FILE * display_result( unsigned short n, size_t size, FILE *fp )
{
    if ( size != 0 )
    {
        display_result( n >> 1, size - 1, fp );
        fputc( ( n & 1 ) + '0', fp );
    }
    
    return fp;
}

FILE * bit_image( unsigned short n, FILE *fp )
{
    display_result( n, sizeof( unsigned short ) * CHAR_BIT, fp );
    
    return fp;
}

int main(void) 
{
    for ( unsigned short i = 0; i < 16; i++ )
    {
        fputc( '\n', bit_image( i, stdout ) );
    }
    
    return 0;
}

The program output is

0000000000000000
0000000000000001
0000000000000010
0000000000000011
0000000000000100
0000000000000101
0000000000000110
0000000000000111
0000000000001000
0000000000001001
0000000000001010
0000000000001011
0000000000001100
0000000000001101
0000000000001110
0000000000001111

The second approach is to have a static local variable that will count recursive calls.

For example

#include <stdio.h>
#include <limits.h>

FILE * display_result( unsigned short n, FILE *fp )
{
    static size_t size;
    
    if ( size != CHAR_BIT * sizeof( unsigned short ) )
    {
        ++size;
        display_result( n >> 1, fp );
        fputc( ( n & 1 ) + '0', fp );
        --size;
    }
    
    return fp;
}

int main(void) 
{
    for ( unsigned short i = 0; i < 16; i++ )
    {
        fputc( '\n', display_result( i, stdout ) );
    }
    
    return 0;
}

The program output is the same as shown above.