steveg@tove.umd.edu (Steve Green) (09/27/89)
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?
--
-steveg@tove.umd.edu ..uunet!tove.umd.edu!steveg
"Ignore the message: 'ld warning: file /tmp/kernAAAa06386 has no relocation
information' if it appears."
earleh@eleazar.dartmouth.edu (Earle R. Horton) (09/28/89)
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 <values.h>. 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
brent@capmkt.COM (Brent Chapman) (09/29/89)
earleh@eleazar.dartmouth.edu (Earle R. Horton) writes:
# 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 <values.h>.
Yeah, _right_. Nice, clear, concise code there. Why shouldn't I reasonably
expect the compiler to do this for me?
-Brent
--
Brent Chapman Capital Market Technology, Inc.
Computer Operations Manager 1995 University Ave., Suite 390
brent@capmkt.com Berkeley, CA 94704
{apple,lll-tis,uunet}!capmkt!brent Phone: 415/540-6400
coolidge@brutus.cs.uiuc.edu (John Coolidge) (09/29/89)
brent@capmkt.COM (Brent Chapman) writes: >earleh@eleazar.dartmouth.edu (Earle R. Horton) writes: ># 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 <values.h>. >Yeah, _right_. Nice, clear, concise code there. Why shouldn't I reasonably >expect the compiler to do this for me? Because it can produce very non-intuitive results. For instance, if the compiler were to do it automatically it's entirely possible that if( ( a == b ) && ( b == c ) && (a != c) ) printf( "What happened?\n" ); would print "What happened?" a lot. The reason is that a could well equal b within the fuzz factor, and b could equal c, but a could be 2*MINDOUBLE away from c's value and hence not be equal. That's why compilers don't automatically generate code to 'fix' problems like this: because it might cause far bigger problems for people doing lots of floating point ops. In general floating point is a big problem --- equality tests on floating point numbers are a bad idea in most languages. Also, things like a*(b+c) often don't equal a*b+a*c, a*(b*c) is often unequal to (a*b)*c, and so on. Followups to comp.lang.c, because this is more a C language issue. It's certainly not specific to A/UX anymore. --John -------------------------------------------------------------------------- John L. Coolidge Internet:coolidge@cs.uiuc.edu UUCP:uiucdcs!coolidge Of course I don't speak for the U of I (or anyone else except myself) Copyright 1989 John L. Coolidge. Copying allowed if (and only if) attributed. You may redistribute this article if and only if your recipients may as well.