Decimal to Binary

I have a number that I would like to convert to binary (from decimal) in C.

I would like my binary to always be in 5 bits (the decimal will never exceed 31). I already have a function that does it manually by dividing but that is hard to pad it to 5 bits.

Is there any easier way? Perhaps using bitwise shift?

I would also like the binary to be represented in a char *

12 Answers

Here's an elegant solution:

void getBin(int num, char *str) { *(str+5) = '\0'; int mask = 0x10 << 1; while(mask >>= 1) *str++ = !!(mask & num) + '0'; } 

Here, we start by making sure the string ends in a null character. Then, we create a mask with a single one in it (its the mask you would expect, shifted to the left once to account for the shift in the first run of the while conditional). Each time through the loop, the mask is shifted one place to the right, and then the corresponding character is set to either a '1' or a '0' (the !! ensure that we are adding either a 0 or a 1 to '0'). Finally, when the 1 in the mask is shifted out of the number, the while loop ends.

To test it, use the following:

int main() { char str[6]; getBin(10, str); printf("%s\n", str); return 0; } 
13

If you don't need leading zeroes, you can just use itoa(value, outputstring, base)

For example

char s[9]; itoa(10, s, 2); printf("%s\n", s); 

will print out

1010 

Else you can just write a very simple function.

void tobin5str(int value, char* output) { int i; output[5] = '\0'; for (i = 4; i >= 0; --i, value >>= 1) { output[i] = (value & 1) + '0'; } } int main() { char s[6]; tobin5str(10, s); printf("%s\n", s); return 0; } 

will print out

01010 

A more generic approach can be a function that ask you how much bits to convert.

void tobinstr(int value, int bitsCount, char* output) { int i; output[bitsCount] = '\0'; for (i = bitsCount - 1; i >= 0; --i, value >>= 1) { output[i] = (value & 1) + '0'; } } 

Of course bitsCount must be a value from 1 to 32, and the buffer string must be allocated for at least bitsCount + 1 characters.

1

One approach is this:

unsigned int x = 30; char bits[] = "00000"; bits[4] = (x & 1) + '0'; x >>= 1; bits[3] = (x & 1) + '0'; x >>= 1; bits[2] = (x & 1) + '0'; x >>= 1; bits[1] = (x & 1) + '0'; x >>= 1; bits[0] = x + '0'; 

Probably not the most elegant approach...

For 31 values, instead of doing malloc to allocate a string, followed by the bit manipulation to fill it, you may just want to use a lookup table.

static const char *bitstrings[] = { "00000", "00001", "00010", … "11111" }; 

Then your conversion is as simple as return bitstrings[i]. If you're doing this often, this will be faster (by avoiding malloc).

Otherwise, you don't really need any shifting (except to make writing your constants easier); you can just use bit-and:

char *bits = malloc(6); bits[0] = (i & (1<<4)) ? '1' : '0'; /* you can also just write out the bit values, but the */ bits[1] = (i & (1<<3)) ? '1' : '0'; /* compiler should be able to optimize a constant! */ ⋮ bits[6] = 0; /* null-terminate string*/ 

There is a (maybe) micro-optimization you can do if you assume ASCII, by using addition. You can also use a loop here, but I needed two lines for the comment :-P. Performance-wise, neither will matter. All the time is spent in malloc.

You can always divide and pad it to 5 bits (did this to pad in 8 bits because printing a character like A would be the number 65 )

#include <stdio.h> #include <math.h> void main(){ int binary[8], number, i; //for 5 bits use binary[5] do{ printf("input a number: "); scanf("%d",&number); fflush(stdin); }while(number>256 || number <0); //for 5 bits... 31 use number>31 || number <0 for (i=0; i<=7; i++) // for 5 bits use i<=4 { binary[i]=number%2; number = number/2; } for (i=7; i >=0; i--) //for 5 bits use i=4 printf("%d", binary[i]); number=0; // its allready 0. for (i=0; i<=7; i++) //for 5 bits use i<=4 { number=number+binary[i]*pow(2,i); } printf("\n%c",number); } 

Since you're only working with 5 bits, why not use a lookup table? Something like the following:

/* Convert nstr to a number (decimal) and put a string representation of the * lowest 5 bits in dest (which must be at least 6 chars long) */ void getBinStr(char *dest, const char *nstr) { char *lkup[32] = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111", "01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001", "10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010", "11011", "11100", "11101", "11110", "11111" }; strcpy(dest, lkup[atoi(nstr) & 0x1f]); } 

Or a switch:

void getBinStr(char *dest, const char *nstr) { switch (atoi(nstr)) { case 31: strcpy(dest,"11111"); break; case 30: strcpy(dest,"11110"); break; ... case 1: strcpy(dest,"00001"); break; case 0: strcpy(dest,"00000"); break; default: strcpy(dest,"error"); } } 

Or if that seems too long, maybe something like the following:

void getBinStr(char *dest, const char *nstr) { unsigned x = atoi(nstr); dest[0] = (x & 0x10) ? '1' : '0'; dest[1] = (x & 0x08) ? '1' : '0'; dest[2] = (x & 0x04) ? '1' : '0'; dest[3] = (x & 0x02) ? '1' : '0'; dest[4] = (x & 0x01) ? '1' : '0'; dest[5] = '\0'; } 

I would normally favour one of the first two, but the last one might be better if for some reason the others are too big (such as code for small microcontroller).

These all assume you want the result left padded with zeros to 5 bits.

#include <stdio.h> #include <string.h> char numstr[9024]; int i = 0; void format(int n, int base); void printreverse(char *s); int main() { int testnum = 312; // some random test number format(testnum, 2); // 2 for binary printreverse(numstr); putchar('\n'); return 0; } void format(int n, int base) { if (n > 0) { char tmp = (n % base) + '0'; numstr[i++] = tmp; // If we put this above other two we don't need printreverse, // But then we will have unwanted results in other places of numstr if we can't reset it format(n/base, base); } else numstr[i] = '\0'; // terminating character } void printreverse(char *s) { long len = strlen(s); while (len-->0) putchar(s[len]); } 

Here is C program to convert decimal to binary using bitwise operator with any decimal supported by system and holding only the required memory

#include <stdio.h> #include <string.h> #include <stdlib.h> int main (int argc, char **argv) { int n, t = 0; char *bin, b[2] = ""; scanf("%d", &n); bin = (char*)malloc(sizeof(char) + 2); while (n != 0) { t = n >> 1; t = t << 1; t = n - t; n = n >> 1; itoa(t, b, 10); bin = realloc((char*)bin, sizeof(char) + 1); strcat(bin, b); } strrev(bin); printf("\n%s\n", bin); return 0 ; } 
#include<stdio.h> int mask = 1; void decToBi(int); void decToBi(int n){ for(int j=15;j>=0;j--){ int result; result = n & (mask<<j); if(result) printf("1"); else printf("0"); } } int main(){ int n; scanf("%d",&n); decToBi(n); printf("\n"); return 0; } 

Hope this helps

My take:

char* to_bitstring(uint32_t val, char buffer[], int size) { buffer[--size] = 0; while (size > 0) { buffer[--size] = (val % 2 ? '1' : '0'); val = val >> 1; } return buffer; /* convenience */ } 

This will write SIZE characters to BUFFER:

char buffer[17]; printf("%s\n", to_bitstring(42, buffer, sizeof(buffer))); 

And will print:

0000000000101010 
int main() { int n,c,k; printf("Enter_an_integer_in_decimal_number_system:_"); scanf("%d",&n); printf("%d_in_binary_number_system_is:_", n); for (c = n; c > 0; c = c/2) { k = c%2; k = (k>0)? printf("1"):printf("0"); } getch(); return 0; } 
#include "stdio.h" #include "conio.h" int main(void) { int i, d , n = 1; int store[10]; printf("Please enter a number to be converted to binary:\n"); scanf("%d",&d); for (i=0;i<8 ;i++ ) store[i] = 0; i = 0; do{ if(d & n ){ n <<= 1; //10 store[i] = 1; i++; } else { n <<= 1; store[i] = 0; i++; } }while(n <= d); printf("\n"); for (i=7;i>=0 ;i-- ){ printf("%d",store[i]); if(i == 4) printf(" "); } printf("\n"); return 0; } 
1

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like