-3

This code is an example from a book that the problem require to change decimal to binary number using bitwise AND operator and the shift operator. I cannot understand the code although had tried to understand this code using debug compiler.

Suppose that for a and b the user input is 10 and 8

#include <stdio.h>
#include <stdlib.h>


int count_bits (unsigned x)
{

    int bits=0;
    while(x){
        if (x&1U)bits++;
            x>>=1;


    } return bits;
}

int int_bits(void)
{
    return count_bits(~0U);
}

void print_bits(unsigned x)
{
    int i;
    for(i=int_bits(x)-1;i>=0;i--)
        putchar(((x>>i)&1U)?'1':'0');
}
int main(void)
{
 unsigned a,b; /*suppose user input a=10 b=8*/
 printf("enter two positive integer value=\n");
 printf("a=  "); scanf("%u",&a);
 printf("b:  "); scanf("%u",&b);

 printf("\na   =");  print_bits(a);
 printf("\na   =");  print_bits(b);
    return 0;
}

In int_bits function what actually (~0U) does? I this meaning to change 0 to 1?

I know it calls count_bits function and return count bits(~0) value but why the x here is somewhat random memory address like 4294967295?

Maybe is it because int int_bits(void) and int_bits() so no parameter and x change from 10 to a random address?

And the count_bits function is here to count how many bits?

while (4294967295)  {
if(x&1u)-> (means compare x last digit value with 1) if true, bits ++;
x>>=1; }-> this mean to shift 1 digit of x to right which mean to divide with 2 until quotien is 0

and when I tried to debug I got 32 for bits value
Why produce 32? is this relate to (~0U) so all bits were 1 or the remains of division?

print_bits (unsigned x) function, is to produce the result
for(i=int_bits()-1;i>=0;i--)
putchar(((x>>i)&1u)?'1':'0')
the x in this value is 10,8 (user input)
and i is 31 from return bits
32-1=31 will be looping until 0

10>>30 means shift 31 to right in just 10?

How it can produce 1010?

What this code actually compare to produce 1010?

Actually the program also produce 32 digit with 1010 in the end.

fiksx
  • 176
  • 1
  • 15

1 Answers1

1
print_bits(unsigned x):

The code takes the last bit of the decimal number using & 1u (same as & 0000000000000001), and then uses the ternary operator to put a '1' if the last bit is 1 (true) and 0 if the last bit is 0 (false). The number is also shifted right one more bit in each step (due to i being incremented) in order to make every bit be obtained by using & 1u.

The & (and) operator compares each corresponding bit in two numbers and creates a bit of 1 if there are two 1's, and 0's in all other cases.

This:

int i = (0101/**/0111) & (0010/**/0101);

Would give i a value of this:

0000/**/0000/**/0000/**/0101 // The addition of two sets of 4 0's on the 
                             //left was due to me assuming int is 32 bits in your system.

Shifting this right by 1 (>> 1):

1101

Would produce this:

0110 

Shifting multiple times allows all bits to be checked by the ternary statement.

count_bits (unsigned x):

The lowest bit of x is evaluated to see if it is 1, while incrementing bits, which stores the number of bits. x is only shifted right if x is 1, thereby making it so that all the 1's in x are set to 0 (I would have just shifted x right with every iteration of bits (the result would be the same).

int_bits(void) converts all the 0's in count_bits to 1's so that it can be used as a way for the loop to know when to stop

AppWriter
  • 247
  • 2
  • 13
  • & operator compare x and 1U, the x what i get is 4294967295 and compare to 0000000000000001? 4294967295, is automatically change to binary? and shift right one more bit means to divide x with 2? – fiksx May 13 '17 at 11:50
  • @devina "Decimal" refers to being base 10, and shifting right allows the lowest bit of the number to become what used to be a higher bit, in order for the & operator to isolate that bit (instead of the original first bit every time). – AppWriter May 13 '17 at 12:05
  • i understand how & operator and the shifting operator work but in this code while x{ if (x&1U) bits++ x>>=1;}. what is the value of x? and what is the relation with count_bits(~0)? 10 in decimal will produce 1010 in binary how the operator & work to produce 1010 in printf? – fiksx May 13 '17 at 12:20
  • @Devina int_bits(void) converts all the 0's in count_bits to 1's so that it can be used as a way for the loop to know when to stop. – AppWriter May 13 '17 at 14:03
  • in tis code int_bits() value is 31 right? is it possible to change for condition in print_bits function to for (i=int_bits();i>0;i--?)? – fiksx May 13 '17 at 14:54