Reputation: 21059
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 *
Upvotes: 14
Views: 63763
Reputation: 1
#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;
}
Upvotes: 0
Reputation: 1
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;
}
Upvotes: 0
Reputation: 2611
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
Upvotes: 0
Reputation: 11
#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
Upvotes: 0
Reputation: 3460
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 ;
}
Upvotes: 0
Reputation: 3894
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);
}
Upvotes: 1
Reputation: 806
#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]);
}
Upvotes: 0
Reputation: 9385
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.
Upvotes: 0
Reputation: 9080
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.
Upvotes: 15
Reputation: 51197
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.
Upvotes: 1
Reputation: 17535
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;
}
Upvotes: 19
Reputation: 471569
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...
Upvotes: 4