Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C printing bits

Tags:

c

I am trying to write a program in C that prints bits of int. for some reason i get wrong values,

void printBits(unsigned int num){
    unsigned int size = sizeof(unsigned int);
    unsigned int maxPow = 1<<(size*8-1);
    printf("MAX POW : %u\n",maxPow);
    int i=0,j;
    for(;i<size;++i){
        for(j=0;j<8;++j){
            // print last bit and shift left.
            printf("%u ",num&maxPow);
            num = num<<1;
        }
    }
}

My question, first why am i getting this result (for printBits(3)).

MAX POW : 2147483648 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 2147483648 214748364 8

second is there a better way to do this ?

like image 313
sam ray Avatar asked Feb 14 '12 16:02

sam ray


2 Answers

You are calculating the result correctly, but you are not printing it right. Also you do not need a second loop:

for(;i<size*8;++i){
    // print last bit and shift left.
    printf("%u ",num&maxPow ? 1 : 0);
    num = num<<1;
}

If you'd like to show off, you could replace the conditional with two exclamation points:

printf("%u ", !!(num&maxPow));
like image 57
Sergey Kalinichenko Avatar answered Sep 29 '22 20:09

Sergey Kalinichenko


How about this Macro:

#define print_bits(x)                                            \
  do {                                                           \
    unsigned long long a__ = (x);                                \
    size_t bits__ = sizeof(x) * 8;                               \
    printf(#x ": ");                                             \
    while (bits__--) putchar(a__ &(1ULL << bits__) ? '1' : '0'); \
    putchar('\n');                                               \
  } while (0)

char c = 3;
int i = -1;
print_bits(c);
print_bits(i);

output:

c: 00000011
i: 11111111111111111111111111111111

This Marco can be used on any primitive datatype and the expression 'x' will be evaluated only once. So you should be safe from side effects.

With the typeof construct you could extend this to structures too:

#define print_bits(x)                                             \
  do {                                                            \
    typeof(x) a__ = (x);                                          \
    char *p__ = (char *)&a__ + sizeof(x) - 1;                     \
    size_t bytes__ = sizeof(x);                                   \
    printf(#x ": ");                                              \
    while (bytes__--) {                                           \
      char bits__ = 8;                                            \
      while (bits__--) putchar(*p__ & (1 << bits__) ? '1' : '0'); \
      p__--;                                                      \
    }                                                             \
    putchar('\n');                                                \
  } while (0)

print_bits((struct in_addr){.s_addr = 0xff00ff00});

output:

(struct in_addr){.s_addr = 0xff00ff00}: 11111111000000001111111100000000

Could be useful e.g. in print debugging.

(typeof is a GNU-extension, use __typeof__ instead if it must work in ISO C programs)

like image 28
breiters Avatar answered Sep 29 '22 22:09

breiters