Path: utzoo!attcan!uunet!ginosko!gem.mps.ohio-state.edu!tut.cis.ohio-state.edu!purdue!bu-cs!dartvax!eleazar.dartmouth.edu!earleh From: earleh@eleazar.dartmouth.edu (Earle R. Horton) Newsgroups: comp.unix.aux Subject: Re: Bug? Message-ID: <15852@dartvax.Dartmouth.EDU> Date: 28 Sep 89 05:28:36 GMT References: <19831@mimsy.UUCP> Sender: news@dartvax.Dartmouth.EDU Reply-To: earleh@eleazar.dartmouth.edu (Earle R. Horton) Organization: Thayer School of Engineering Lines: 43 In article <19831@mimsy.UUCP> steveg@tove.umd.edu (Steve Green) writes: > >Why does this program print "no" under AUX and print "yes" on this vax? > >main () >{ > double x = .5; > > if (.4 <= x - .1) > printf ("Yes\n"); > else > printf ("No\n"); >} > >What am I missing? Is it time for me to re-read my K&R?? >Is it just my AUX that is doing it? System V? A/UX gives the seemingly false result because the temporary used to hold "x - .1" is a 68881 register. These registers hold two bytes more of information than a double. The temporary is not rounded after the computation of "x - .1," and so the equality test fails. If you trace through this code using sdb to single-step machine instructions, you will see what is happening here. I don't think K&R says anything about this, because K&R assumes that "double" is the natural size for a floating point quantity in the local implementation. In this case, that is false. The natural size is mc68881 96-bit extended. Note that floating point constants are stored in 64 bits, not 96. It is in general bad practice to apply an equality test to the result of a computation. Instead of ( a == b ) use ( ( a < b + MINDOUBLE ) && ( a > b - MINDOUBLE ) ) MINDOUBLE is in. Furthermore, if the computation is very involved, then the machine result may diverge from the ideal result by more than this. All the gory details may be found in any good textbook on numerical methods. Earle R. Horton