Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!mordor!sri-spam!sri-unix!quintus!ok From: ok@quintus.UUCP (Richard A. O'Keefe) Newsgroups: comp.lang.c Subject: Re: How not to write a loop Message-ID: <730@cresswell.quintus.UUCP> Date: 4 Mar 88 00:55:16 GMT References: <296@draken.nada.kth.se> <64400004@convex> Organization: Quintus Computer Systems, Mountain View, CA Lines: 40 In article <64400004@convex>, cuddy@convex.UUCP writes: c ok@quintus.Sun.COM (our feed trashes addreesses, that may not be right!) c o In article <832@unmvax.unm.edu>, mike@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?}