How not to write a loop

Richard A. O'Keefe ok at quintus.UUCP
Fri Mar 4 10:55:16 AEST 1988


In article <64400004 at convex>, cuddy at convex.UUCP writes:
c ok at quintus.Sun.COM (our feed trashes addreesses, that may not be right!)
c o In article <832 at unmvax.unm.edu>, mike at turing.UNM.EDU (Michael I. Bushnell) writes:
c o m I see NOTHING which precludes:
c o m 	float x; for (x = 0; x < 20; x += .5) printf("%f ", x);
c o m The output would, of course, be
c o m 	0.0 0.5 ... 19.5
c o Quite right, there is nothing in K&R (or dpANS) to prohibit this.
c o But you have provided a good illustration of why people disparage
c o the use of floating-point variables in loop control.
c o THERE IS NO "OF COURSE" ABOUT THAT OUTPUT!
c o You should not be surprised to see as the last value
c o 	19.99999
c 
c Only if you declare things as floats!

If I have understood his posting, Mike Cuddy claims that the problem goes
away if you use 'double' rather than 'float'.  If you believe this,
I have a second-hand bridge you might be interested in buying...

The problem has nothing to do with casting floats to doubles.
The problem is that floating-point arithmetic is APPROXIMATE.
If you go to double precision, you get a better approximation,
perhaps even a very good one, but it is still an approximation.
If the least significant bit out of 53 is wrong, that can still
be enough to make a loop execute one time too many or one time
too few.

Note that there are perfectly sensible loops where the control variable
is float (or double), e.g.

	while (fabs(y*y - x) > eps) { compute next y }

The point at issue is that if you use floats (or doubles) for
COUNTING, you are being a fool to yourself and a burden to others,
because your counts will be approximate.

{Actually, this isn't quite true either.  Using a double-precision
variable to hold multiples of 1 is usually safe, and on far too many
machines will give you a larger range of integers than any integral
type.  64-bit integers, anyone?}



More information about the Comp.lang.c mailing list