PDA

View Full Version : Decimal to binary in C


Dr_s99
10-23-05, 01:15 PM
hello
i'm trying to make a program to convert Dec to binary!
i have finnished the program but my problem is that when the answer is printed on screen its backward!


#include<stdio.h>

void main(void)
{
int posnumber,binnum;

printf("Enter a positive number : ");
scanf("%d",&posnumber);

while(posnumber<0)
{
printf("Enter a positive number : ");
scanf("%d",&posnumber);
}

while (posnumber!=0)
{

binnum=posnumber%2;
posnumber=posnumber/2;


printf("%d\n",binnum);

}
printf("\n");
}


I don't want to use Array's ...!

mo_x
10-23-05, 05:00 PM
How about a recursive function call :D

#include<stdio.h>

void printbin(int num)
{
int binnum;

binnum=num%2;
num=num/2;

if (num!=0) printbin(num);

printf("%d",binnum);

return;
}

int main(void)
{
int posnumber,binnum;

printf("Enter a positive number : ");
scanf("%d",&posnumber);

while(posnumber<0)
{
printf("Enter a positive number : ");
scanf("%d",&posnumber);
}

printbin(posnumber);
printf("\n");

return 0;
}

Dr_s99
10-23-05, 07:37 PM
is there any other way which i could do this without using Functions?

de><ta
10-23-05, 10:36 PM
void int_to_bin(char *out, unsigned n)
{
unsigned mask = ~(~0u >> 1);
while (mask)
{
*out++ = n & mask ? '1' : '0';
mask >>= 1;
}
*out = '\0';
}


You could convert the while statement to a for loop which would further improve pipelining. For a normal signed integer, convert the most significant bit to 0.

Using a recursive method for this is too inefficient.

DaveW
10-24-05, 01:57 PM
or you could cheat and use the System.Convert class in the .NET framework :)

Riff
10-24-05, 02:26 PM
If your program is not time critical, any moderately efficient implementation will suffice. If you absolutely have to optimize then I suggest this implementation, assuming that the unsigned data type is 32 bits wide:

void int_to_bin(char *out, unsigned n)
{
unsigned int i;

out = &out[32];
*out = '\0';

for(i = 32; i > 0; i--)
{
*(out--) = ((n & 1) + '0');
n >>= 1;
}
}

This implementation works for both signed and unsigned integers and avoids mispredicted branches. You don't want to calculate the proper character to print using a conditional branch because the binary digits are not predictable and you almost always be guaranteed at least one cache flush for input values other than 0 and -1 due to misprediction of the branch target. The character to be printed is easily computed without branches: the correct character is always '0' plus the value of the binary digit.

Note that my implementation generates the binary string from lsb to msb. This will have no effect on the cache and working backwards allows the use of a constant boolean mask (n & 1 rather than n & mask).

Dr_s99
10-24-05, 02:52 PM
first off.. thank you everyone for your reply!
i came with another idea...!

#include<stdio.h>
#include<math.h>

void main(void)
{

int num,rem,binnum,power=0;

scanf("%d",&num);

while(num!=0)
{
rem=num%2;
binnum=rem*pow(10,power)+binnum;
num=num/2;
power++;
}
printf("%d",binnum);
printf("\n");
}

Riff
10-24-05, 03:59 PM
If you absolutely cannot use arrays, your second implementation will work but you can optimize it a little bit. First of all, change "num%2" and "num/2" to "num & 1" and "num >> 1" just in case the compiler is too stupid to do that optimization automatically. Additionally, each power used is simply ten times the previously used power so you can avoid making a call to power:


void main(void)
{
int num,rem,binnum,power=0;

scanf("%d",&num);

while(num!=0)
{
binnum=(num & 1)*power+binnum;
num >>= 1;
power *= 10;
}
printf("%d",binnum);
printf("\n");
}


Be aware that this is going to be slower than previously suggested implementations due to the fact that the final printf is going to use the correspomding inverse algorithm to convert each digit back to a a character. If you use the previously suggested implementation, you are using an array but you are avoiding the initial loop which does nothing but convert one binary number into another binary number.

gmontem
10-24-05, 07:55 PM
is there any other way which i could do this without using Functions?
Template metaprogramming would be another solution if the number to be converted is known during compilation and you're not constrained to the C language. I haven't verified the correctness of my code below but there is unfortunately a ceiling for the value N. Calculating the binary equivalent of at least 1024 will produce a result greater than the maximum data type range for an enum.


template<int N>
struct Dec2Binary
{
enum { result = ((Dec2Binary<(N >> 1)>::result * 10) + (N & 1)) };
};

template<>
struct Dec2Binary<0>
{
enum { result = 0 };
};

template<>
struct Dec2Binary<1>
{
enum { result = 1 };
};



Dec2Binary<363>::result will produce the binary equivalent 101101011. The result will be calculated not during runtime execution but during compilation which is pretty neat.

wnd
10-25-05, 07:35 PM
"Correct answer" depends on where you want to use this.

In short I'd make a recursive function:

void
dec2bin(int n)
{
if (n) {
dec2bin(n >> 1);
putchar('0' + (n & 1));
}
}


If you just need to print out a couple of binary numbers, recursion should be "good enough". Recursion, in this case, isn't very inefficient either. With modern CPUs L1-cache should easily handle at least 262144-bit integers (== stack should fit in cache).


is there any other way which i could do this without using Functions?


Why wouldn't you want it as a function?

Dr_s99
10-26-05, 10:21 AM
wow.. thanx!