I'm trying to write a C Program to convert a Decimal to Binary. The following code can convert an Integer in Decimal to Binary.
#include <stdio.h>
#include <math.h>
int main()
{
long int n;
printf("Enter a Positive Integer (decimal): ");
scanf("%d", &n);
long int temp = n;
int r; long long int bin = 0;
int p = 0;
while(temp > 0)
{
r = temp % 2; printf("%d\t", r); // printing r value for debugging
bin += (r * pow(10, p));
temp /= 2;
p++;
}
printf("\n%lld", bin);
return 0;
}
I have tested the code for multiple random values and got the expected output for most of them except two particular values '99999' and '419862'. For '99999', the expected output is '11000011010011111', But instead I get '11000011010011112'. And for '419862', the expected output is '1100110100000010110', But instead I get '1100110100000010112'. All digits but the last one's match correctly. Getting a '2' instead of '1' and '0'. To Debug the code I added a printf("%d\t", r); immediately after the r = temp % 2; statement. The r values so printed give the correct expected output. Here is the output:
For '99999' the output is
Enter a Positive Integer (decimal): 99999
1 1 1 1 1 0 0 1 0 1 1 0 0 0 0 1 1
11000011010011112
For '419862' the output is
Enter a Positive Integer (decimal): 419862
0 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 1 1
1100110100000010112
Caution: The r values printed individually are in reverse.
Why is the first remainder value printed using printf("%d\t", r); '1' and '0' respectively
(for '99999' and '419862'), But the unit digits of bin value obtained by Compound Assignment not the same?
bin += (r * pow(10, p));meansbin = bin + (r * pow(10, p));. (N1570 6.5.16.2 Compound assignment)According to usual arithmetic conversions (N1570 6.3.1.8), multiplication
*and addition+will yielddoubleresult when one of their operands isdouble(and the other one is real type and notlong double).The
powfunction (N1570 7.12.7.4) returnsdouble, sor * pow(10, p)has typedouble, and thereforebin + (r * pow(10, p))also has typedouble.Typically 64-bit IEEE754 format is used for
double. It is said that the presicion of this format is about 15 decimal digits.In the last iteration with input
99999, values1000011010011111and10000000000000000are added. They has 16 and 17 digits, respectively. This exceeds the 15-digit limit and the chance to get precision errors becomes high.In conclusion, you are getting rounding error because you used floating-point values where integers with many digits should be used.
For example, the use of
powin this case can be eliminated in this way (use a multiplier variablemultand incrementaly multiply10to that instead calculating the power in each iteration):