Path: utzoo!utgpu!news-server.csri.toronto.edu!me!writer Newsgroups: comp.lang.c From: writer@me.utoronto.ca (Tim Writer) Subject: Re: Inherent imprecision of floating point variables Message-ID: <90Jun28.052240edt.18563@me.utoronto.ca> Organization: University of Toronto, Department of Mechanical Engineering References: <3300@crash.cts.com> <44436@ism780c.isc.com> Date: 28 Jun 90 09:22:52 GMT In article dylan@ibmpcug.co.uk (Matthew Farwell) writes: >main() >{ > float f; > f = 0.0; > while (1) { > if (f == 10.0) break; > printf("%f\n", f); > f += 0.1; > } > printf("Stopped\n"); >} >If its all to do with conversion routines ... As has been mentioned in several earlier postings, it is *not* all to do with conversion routines. It *is* to do with the fact that no floating point system can represent any real number exactly. Your documentation will tell you that a float can represent real numbers within in a specific interval. However, since we know there are an infinite number of reals in any given interval, we can deduce that your floating point system can only represent a relative few of these numbers exactly. Thus, when you write `0.1' and `10.0' in your program, your computer may not store exactly `0.1' or `10.0'. Then, when you continuously add `0.1', you are not actually adding `0.1' but some value close to `0.1'. The result is you never get `10.0' because you have accumulated some error in `f'. Try this program. main() { float f, stop; f = 0.0; stop = 10.0; while (1) { if (f == stop) break; f += 0.1; (void) printf("f=%.20f\tstop=%.20f\n",f,stop); } } Now try this program. main() { float eps, tst; eps=1.0; do { eps=0.5*eps; tst=eps+1.0; } while (tst>1.0); (void) printf("%.10e\n",eps); } This gives an approximation of machine epsilon which differs from its real value by at most a factor of 2. Machine epsilon is defined to be the smallest number which when added to 1 produces a result which is greater than 1. It is a measure of the relative error in the floating point representation of real numbers. On my system, this program gives a value of roughly 5.9e-8. In other words, I can represent floats with about 8, yes *only* 8 digits accuracy. Or, to rephrase, any digits following the eighth digit of the mantissa are garbage. Tim