0

As in title i'm trying to convert decimal number to binary. I set the lowest int as i coudl

char * toBinary(int num)
{

    int i = 1 << 31;
    while(i!=0)
    {
        if((num & i) == 0 )
            printf("0");
        else
            printf("1");
        i >>= 1;
        printf("%d", i);
        getchar();
    }
}

but it does not work, after every shift i is still negative number, what shoudl i change ?

whd
  • 1,819
  • 1
  • 21
  • 52

2 Answers2

6

There are several errors both with your code and with your description of what it does. Here is a corrected version:

void print_binary(unsigned x)
{
    for (unsigned bit = 1u << 31; bit != 0; bit >>= 1)
        putchar((x & bit) ? '1' : '0');
}

Errors:

  • The function should not return char *, since it doesn't return anything. If you want to make a function that returns a string, that is different.

  • You cannot compute 1 << 31, because that is an overflow. You must use unsigned numbers: 1u << 31 is okay (assuming int is 32 bits).

  • You are not converting from decimal to binary. The input number is already in binary, you are simply printing it out in binary.

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
  • i thought only difference between int and unsigned int is that last bit is sign bit, why i cant shift signed int like i did ? – whd Oct 08 '13 at 17:30
  • The problem is that when you shift a signed number to the right it "sign fills". An unsigned number is zero-filled. – Hot Licks Oct 08 '13 at 17:43
  • @whd Before coming to SO I was also unaware of this, similarly one more interesting thing is `~0` is undefined (or may be implementation) where as `~0u` is well defined!! – Grijesh Chauhan Oct 08 '13 at 17:59
3

Use unsigned i.

int i = 1 << 31;

correct as:

unsigned int i = 1u << 31;

Additionally, instead of using 31 I would like to suggest you to write size independent code (size of int can be different in different machine).

Do like:

unsigned int mask = 1u << ((sizeof(unsigned int) * CHAR_BIT) - 1);   

I have named mask instead i, write like this code.

//conversion 
unsigned int mask = 1u << ((sizeof(unsigned int) * CHAR_BIT) - 1);   
while(mask > 0){
  if((num & mask) == 0 )
       printf("0");
  else
       printf("1")
   mask = mask >> 1 ;  // Right Shift 
}

From @Carl Norum's comment: To correctly write a size platform independent code use CHAR_BIT macro defined in limits.h header file. Note CHAR_BIT is the number of bits in char and it is possible that in some implementation of C a byte may not be equals to 8 bits.

Read: What is CHAR_BIT?

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208