### Thread: float numbers slightly out

Page 1 of 2 12 Last
1. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16

#### float numbers slightly out

the code below gets numbers from freeform input and puts those numbers into an array of floats and prints that array. it all works fine apart from sometimes the decimal numbers are just slightly out, for example if this is input:

5.5 45.8 -99.01

the resulting floating point numbers that are printed out are:

5.500000
45.799999
-99.010002

so the first number's fine but then the next two numbers are slightly off for some reason. any idea why that is?

Code:
```/* getfloat5-2.c: make floating point number array out of numbers found in freeform input.
(not quite working but nearly - odd small decimal inaccuracies on the end
sometimes for some reason.) */

#include <stdio.h>
#include "getch.c"
#define SIZE 100

main()
{
int i, n, x, getfloat(float *);
float array[SIZE];

for(n=0; n < SIZE && (i=getfloat(&array[n])) != EOF; n++)
if(i==0)	/* not a number - try to fill same array element again */
n--;

printf("# of #'s: %d\n", n);

for(x=0; x < n; x++)		/* print the results */
printf("%f\n",array[x]);
}

/* getfloat: get next float from input into *pn */
int getfloat(float *pn)
{
int c, sign;
float fraction;

while(isspace(c=getch()))	/* skip white space */
;
if(!isdigit(c) && c != EOF && c != '+' && c != '-' && c != '.')
return 0;		/* it's not a number */
sign=(c=='-') ? -1 : 1;		/* record pos or neg */
if(c=='+' || c=='-') {
c=getch();
if(!isdigit(c) && c != EOF)
return 0;
}
for(*pn=0.0; isdigit(c); c=getch())	/* get integer part of number */
*pn=10 * *pn + (c-'0');

fraction = 1.0;
if(c=='.') {		/* there's possibly a fraction part to come */
while(isdigit(c=getch())) {
*pn = 10.0 * *pn + (c - '0');
fraction *= 10.0;
}
}
*pn = sign * *pn / fraction;
if(c != EOF)
ungetch(c);
return c;
}```
2. No Profile Picture
Contributing User
Devshed Beginner (1000 - 1499 posts)

Join Date
Feb 2001
Posts
1,481
Rep Power
19
I believe it has something to do with the fact you are storing a base 10 number in bytes which are in base 2(on or off, or 0 or 1), so the representation isn't exact.
3. See this FAQ
http://www.eskimo.com/~scs/C-faq/q14.1.html
Hope this helps! :)
4. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
right, i see. thanks v. much for the replies. i changed all the floats to doubles and got:

5.500000
45.800000
-99.010000

from:

5.5 45.8 -99.01

so that's good. thanks :)
5. No Profile Picture
Contributing User
Devshed Newbie (0 - 499 posts)

Join Date
Nov 2002
Location
Blacksburg VA/Philly PA
Posts
38
Rep Power
16
floats are more accurate than doubles, but if you are doing something that needs to be exact convert from floats to something like an unsigned int. then make an enumerated type to take care of the sign issues, then wrap it all together into a class. this should fix all the issues (of you have time to do it and everything)
6. >> floats are more accurate than doubles
It's the other way around.
7. Originally posted by balance
right, i see. thanks v. much for the replies. i changed all the floats to doubles and got:

5.500000
45.800000
-99.010000

from:

5.5 45.8 -99.01

so that's good. thanks :)
Remember that these numbers only appear to be correct since double stores more digits (binary digits) than you are actually outputting. As 7stud stated, some base 10 numbers cannot be stored exactly in base 2, no matter how many bits the floating point representation of it stores. Try and show more digits for the above, and you'll see that they, too, are not accurate. Perhaps they are now as accurate as you like them to be, though.
8. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
right. i had a feeling that may be the case.

i am quite surprised at this:- decimal numbers being innacurate on computers. very surprised even. never struck that that could be a problem or issue for them.
9. Remember that this is only the case for fractional values. Integers are stored perfectly in both INTEGER and FLOAT types (up to the storage limit, anyways).

Also, if you think about it, it is not all that surprising that you cannot store some values accurately in base-2. You cannot store the 1/3 in base-10 accurately:
0.33333333333333333...
as you can only store so many 3's, even though 1/3 stores easily in base-3:
0.1.

This is the exact same problem as trying to store 1/10 in base-2:
0.00011001100110011...
even though it stores accurately in base-10:
0.1

Also consider that you cannot store a number such as PI accurately in any base.
10. Something else you may be interested in:

Most calculators use Binary Coded Decimal (BCD) for storing numbers, which stores either 1 or 2 decimal digits per byte. So, the computations are done using decimal digits (this is not normally used for PCs since it is an awful waste of memory).

This doesn't mean they are more accurate than base-2 storage of most CPUs, since it all depends on the amount of digits that are stored. My TI-85 stores 14 internal decimal digits and only displays 12, so the inaccuracy is not apparent except for when the accumulative error of multiple calculations makes at least 3 of the end digits of the 14-digit result inaccurate.

Also, as I have explained above, certain numbers simply do not store accurately in certain bases. You can never get away with this. Base-10 is not, by any means, some perfect base. Some numbers store perfectly in some bases, and not in others - it all depends on the numbers and the base you are using.
11. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
so maybe the wrong base has been used for pi? if you used the right base then you'd be able to fully and accurately describe it?
12. Nope, pi can't be described accurately in any base. pi, e, sqrt(2) etc. all belong to a class of numbers called irrational numbers. However, a discussion about irrational numbers is beyond the scope of this forum, so google for more info, if you're interested :)
13. Originally posted by balance
so maybe the wrong base has been used for pi? if you used the right base then you'd be able to fully and accurately describe it?
No, please re-read the above two posts very carefully, because you do not understand exactly what I am saying. I said, "Also consider that you cannot store a number such as PI accurately in any base."

Basically, computers are finite machines - they can store only a limited amount of information. Therefore, when you have more information to store than space to store it, you must lose some information. In terms of a number, we discard the most insignificant digits.

Numbers such as pi and e cannot be described with a finite number of digits in any base, so no matter what base you choose, you have to stop storing digits when you run out of memory.

Other numbers, such as 1/10, can be stored with a finite number of digits in base 10, like so: 0.1, and therefore it can be accurately stored in a computer system using base-10 (like most calculators that use BCD - binary coded decimal, which is base-10). But, when you try and store it in base-2, you get a repeated number, and therefore you must stop storing digits when you run out of space. Therefore, what you stored is not exactly 1/10. Hopefully, though, you only need 10 or 12 digits of accuracy, and since double can store 15 or 16, then this is good enough.

I hope this clears things up for you.
Last edited by Jason Doucette; March 4th, 2003 at 02:48 PM.
14. No Profile Picture
.
Devshed Newbie (0 - 499 posts)

Join Date
Dec 2002
Posts
296
Rep Power
16
irrational numbers - i like that.

it was just a thought - forget it. :) thanks very much.
15. If you could get PI to be accurately described in a base, then we would have a fraction that could describe PI. Why? Because, let's say you have a number like so:

0.abcdefgh

where a through h are all digits of whatever base we are in (let's say base x), then this number can be described by this fraction:

abcdefgh / x^8

The 8 comes from the fact that there are 8 digits. Let me show you a simplier example of this, if you have this number:

0.274 (in base-10, decimal)

this can be described as:

274 / 10^3 (which is equal to: 274 / 1000 which equals 0.274)

PI cannot be described by a fraction (an integer divided by another integer), so it cannot be described accurately in any base, and is therefore an irrational number.
Page 1 of 2 12 Last