# Correct my code as it is giving approximate float value but not exact

Printable View

• 07-15-2011
ackr1201
Correct my code as it is giving approximate float value but not exact
Code:

```//code to convert string(containing digits) to equivalent float value //Its giving approx value but not exact value #include<stdio.h> #include<ctype.h> #include<math.h> int main() {     char a[20];     int c,i=0,k,sign=1;     float f=0;     while((c=getchar())!='\n' && i<19)     {         a[i]=c;         i++;     }     a[i]='\0';     for(i=0;a[i]==' ' && i<19;i++)     ;     if( (a[i]=='+' && (sign=1)) || (a[i]=='-' && (sign=-1)) )         i++;     for(;a[i]!='\0'&&a[i]!='.';i++)     {         f=f*10+(a[i]-'0');     }     if(a[i]=='.')         for(k=-1,i++;a[i]!='\0';i++,k--)             f=f+pow(10,k)*(a[i]-'0');     f*=sign;     printf("\n num is %f",f);     return 0; } o/p: 123.654  num is 123.653999```
• 07-15-2011
tabstop
That's working as designed.
• 07-15-2011
ackr1201
I got output as shown above. I did on gcc compiler....
• 07-15-2011
tabstop
And that is the correct output.

See here: IEEE-754 Reference Material
• 07-15-2011
quzah
Do you think the 32bits representing a float should be able to give you more digits than the 32 bits representing an integer? Wouldn't that make integers completely pointless? If you want accuracy, use integers. If you want estimations of floating point numbers, use floats or doubles.

Quzah.
• 07-15-2011
CommonTater
Quote:

Originally Posted by ackr1201
Code:

```//code to convert string(containing digits) to equivalent float value //Its giving approx value but not exact value #include<stdio.h> #include<ctype.h> #include<math.h> int main() {     char a[20];     int c,i=0,k,sign=1;     float f=0;     while((c=getchar())!='\n' && i<19)     {         a[i]=c;         i++;     }     a[i]='\0';     for(i=0;a[i]==' ' && i<19;i++)     ;     if( (a[i]=='+' && (sign=1)) || (a[i]=='-' && (sign=-1)) )         i++;     for(;a[i]!='\0'&&a[i]!='.';i++)     {         f=f*10+(a[i]-'0');     }     if(a[i]=='.')         for(k=-1,i++;a[i]!='\0';i++,k--)             f=f+pow(10,k)*(a[i]-'0');     f*=sign;     printf("\n num is %f",f);     return 0; } o/p: 123.654  num is 123.653999```

Congratulations.... your program works.

And yes... computers do indeed make mistakes.
Floating point math on computers is always an approximation limited by the bit depth of the calculation...
• 07-15-2011
anduril462
In base 10, 2/3 is 0.666666.... It never ends, and you can never represent 2/3 perfectly with only a finite number of digits. Furthermore, when you give a truncated value (say, only 5 decimal places), you typically round to 0.66667. It's inexact, but close enough for most things.

Computers use base 2, but just like base 10, some fractions can't be represented perfectly. Also, they are limited to the number of bits they can use for floating point representation, so they get as close as they can, but it might not be perfect. In base 10, 123.654 is an exact representation of the quantity 123654 / 1000, but 123654 / 1000 doesn't have an exact representation in base 2, hence the approximation.

If you asked for only 3 places after the decimal (what you're currently asking for is the default, 6), the computer would round to 123.654. Try putting printf("\n num is %.3f", f); and see what happens.

The following article may be a little complicated, but it's a very thorough explanation of how computers handle floats, the shortcomings and how to deal with it.

What Every Computer Scientist Should Know About Floating-Point Arithmetic
• 07-15-2011
ackr1201
See the following code it is giving exact answer compared to my answer
Code:

```//concept took from K&R book void main() { char s[]="123.654"; double val, power; int i=0, sign,c; for (i = 0; isspace(s[i]); i++) //skip white space ; sign = (s[i] == '-') ? -1 : 1; if (s[i] == '+' || s[i] == '-') i++; for (val = 0.0; isdigit(s[i]); i++) val = 10.0 * val + (s[i] - '0'); if (s[i] == '.') i++; for (power = 1.0; isdigit(s[i]); i++) { val = 10.0 * val + (s[i] - '0'); power *= 10; } printf("%f",sign*(val/power)); } O/P: 123.654000```
• 07-15-2011
tabstop
So obviously you can get closer to the right number with a double precision than you can with a float (in fact, you get just about twice as many correct digits). That just moves the "wrong numbers" past the place where printf stops. Try printing with %.18f or something and you'll see the difference.
• 07-15-2011
anduril462
First problem with that code, it's int main(void) and return an int at the end. Read this FAQ article: Cprogramming.com FAQ > main() / void main() / int main() / int main(void) / int main(int argc, char *argv[])

Second, your first bit of code uses float (32 bits of precision), while the second piece uses a double (64 bits of precision). Neither is "exact". If you print enough decimal places, you will see even the second bit of code stores an imprecise number, but rounds it correctly when only printing a few decimal places. Instead of one printf line with the default "%f", put the following at the end of each program:
Code:

```printf("The value to 20 decimal places is %.20f", value); printf("The value to the default (6) decimal places is %f", value); printf("The rounded to 3 decimal places is %.3f", value);```
If you put that in both programs and try both programs, you will see that the number is only an approximation, but using more bits (i.e. double instead of float) gets you closer to exact, so you can print more decimal places before the error becomes apparent.