Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!udel!haven!uvaarpa!murdoch!astsun9.astro.Virginia.EDU!cak3g From: cak3g@astsun9.astro.Virginia.EDU (Colin Klipsch) Newsgroups: comp.sys.mac.programmer Subject: Re: Why can't the Mac add? Summary: Don't use FP indexing Message-ID: <1990Sep24.160108.26148@murdoch.acc.Virginia.EDU> Date: 24 Sep 90 16:01:08 GMT References: <45060@apple.Apple.COM> Sender: news@murdoch.acc.Virginia.EDU Organization: University of Virginia Lines: 64 In article <45060@apple.Apple.COM> das@Apple.COM (David Shayer) writes: >I was running this simple program. >main () >{ > float x; > for (x=0.0;x!=10.0;x+=0.2) > printf ("x=%f \n",x); >} >As you can see, it ought to stop when x==10.0. However, >it actually runs in an infinite loop. This is because >x never equals exactly 10.0. >I have a Mac IIci, so I have a 68882 FPU. This program >fails in both Think and MPW C. I didn't compile with any >special FPU options on. A friend ran it on a >PC clone, and it failed in the same way there. >Please enlighten me. Never, ever, EVER use a floating point variable as a loop index! Not in any language, on any computer, under any circumstances. Do not use them in a box, do not use them with a fox. (This, of course, is my vehement opinion.) Always use integers for the very reason you've discovered: floating point numbers suffer from round-off error for most fractions, and that certainly includes powers of ten. 0.2 represented in binary is infinitely repeating. The computer can't carry around an infinite sequence of bits, so it's loop step is not REALLY 0.2, but the closest binary approximation. (The "double" approximation will be closer than the "float", but will still be unequal.) This is not a defect of your Mac, or the PC. It's a result of the fact that computers work in binary, not decimal. You can usually get away with using floating point numbers in loops IF the variable AND the step size are exactly integers, but it's still a questionable policy. To work around this problem, you could use: for (x = 0.0; x <= 10.0; x += 0.2) {} But the best solution: int i; for (i = 0; i <= 50; i++) { x = i/5.0; ... } This more faithfully generates the results you (presumably) wanted: to have x go from 0 to 10 in 50 evenly distributed intervals. More importantly, your loop is guaranteed to terminate, and it will terminate after the correct number of steps. Hope this helps. -------------------------------------------------------------------------- "May the forces of evil become confused on the way to your house." -- George Carlin Bemusedly, | Disclaimers: Colin Klipsch | Not guaranteed to fulfill any purpose, Property of UVa Ast. Dept. | express or implied. Contents may have Charlottesville, Virginia | settled during shipping. Not rated. May cak3g@virginia.edu | cause drowsiness. Use before 29-Feb. ____________________________/ \___________________________________________