Decimal to Binary
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;
}
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.
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);
}