Floating Point Expectations

Andrew P. Mullhaupt amull at Morgan.COM
Fri Jun 1 03:22:47 AEST 1990


In article <1990May31.001618.24274 at ico.isc.com>, rcd at ico.isc.com (Dick Dunn) writes:
> michael at yonder.UUCP (Michael E. Haws) writes:
> > Is it reasonable to expect that the following code should
> > work the same on all platforms, and produce "good" results?
> > 
> >         if ((45.0 / 100.0) == .45)
> > 		printf("good\n");
> > 	else
> > 		printf("bad\n");
> 
> Leaving aside for a moment all the nasty things that can go wrong with
> floating-point equality, you might note a couple of things here and ask
> some simpler questions:
> 
> Note that the given expression contains a division of a couple of integral
> values in float notation.  On almost all architectures, these should be
> represented exactly.  The question could be interpreted as whether the
> machine is able to do an accurate division for these particular operands.
> 
> Another way to look at it is to think about the process of forming the
> float constant ".45".  This is often done by taking the string of digits
> (45) and scaling by an appropriate power of ten, which is remarkably close
> in semantics to 45.0/100.0.
> 
> Yet a third viewpoint is that the entire expression is constant; a good
> compiler ought to evaluate it carefully.  The likelihood that it will come
> up true, while admittedly not a certainty, ought to be higher than or equal
> to the likelihood that it comes up true if calculated at run time.
> 

On the other hand, consider the possibility that the .45 is converted
to double, as are the exactly representable 45.0 and 100.0. Now if
the division is performed with guard digits, or perhaps in IEEE
extended, then we have to worry about whether or not the comparison
is done strictly as double, or in the wider form. This can depend on
the hardware (do you have a coprocessor or not), on the compiler,
(does it use extended or not), or on the options given to the compiler.
The comparison, if done in the wider format, will result unequal if
the extended and double representations of 45.0/100.0 are not the
same. 

You're probably right that a lot of machines will result in equality
for the given example, but the complexity of ensuring this makes it
an assumption I'd rather skip than justify.

One of the most interesting classes of bugs is based on the failure
of this assumption; a program is developed, but when optimization is
enabled, it breaks because some result which is stored (and therefore
tacitly coerced back to double) is no longer coerced because the
compiler optimized the store/recall sequence away. If you recompile
the program without optimization (as is often necessary) in order to
run the program under a debugger, the bug will go away! 

The hours of enjoyment you might spend chasing this kind of bug 
down is reason enough to steer well clear of code which can be
very sensitive to the floating representation. There are enough
such possible hours that studying numerical analysis and learning
ways to safely exploit fixed and floating point computations (and
a lot of other useful stuff) could be thought of as a time saver.

Later,
Andrew Mullhaupt



More information about the Comp.unix.wizards mailing list