Underflow bug

Fred Tydeman uunet!netcom.com!tydeman
Wed Dec 14 08:54:02 PST 1994


On my system, which has an Intel 80486DX-33Mhz, double numbers converted
to float numbers do not raise underflow as per IEEE-754, in the range of
FLT_MIN to FLT_MIN*(1.0-FLT_EPSILON).
	
IEEE-754 allows underflow to be raised in one of 4 ways:
  (Before or after rounding) x (denormalization loss or inexact result).
	
My Intel 80387 manual says underflow is the result of 'tiny result' and
'inexact result'.  I cannot find any mention if 'tiny result' is before
or after rounding.
	
There appear to be 5 causes for the underflow flag being set incorrectly:
	
1)  The Intel 80x87 architecture is buggy.
2)  The particular 80486DX chip in my machine is buggy.
3)  The compiler generated incorrect code.  Since I do not have a machine
    level debugger, I have no means to verify the actual code executed.
4)  My test cases are buggy.  I have also run my tests on an IBM RISC/6000
    machine and there the underflow flag is rasied as per IEEE-754.  That
    does not prove my code is correct, but it does increase the odds.
5)  My understanding of IEEE-754 underflow.
	
I am asking other numeric experts to test their chips to see if this is
a hardware or a software problem.
	
In the following display, 'excepts' is the IEEE-754 exception flags due
to the conversion.  '00' is no exceptions, '20' is inexact, '30' is
underflow and inexact.
	
The 'dbl=' value is the double value being converted to float.
The 'flt=' value is the result after the conversion.
	
FLT_MIN and FLT_EPSILON come from C's float.h header file.  FLT_MIN is
the smallest normalized float number.  FLT_EPSILON is the difference
between 1.0 and the next greater representable float number.
	
Linear display starting from FLT_MIN going downward toward
FLT_MIN*(1.0-FLT_EPSILON).
	
excepts=00, dbl=3810000000000000, flt=00800000  Exactly FLT_MIN
excepts=20, dbl=380fffffff000000, flt=00800000
excepts=20, dbl=380ffffffe000000, flt=00800000
excepts=20, dbl=380ffffffd000000, flt=00800000
...
excepts=20, dbl=380ffffff1000000, flt=00800000
excepts=20, dbl=380ffffff0000000, flt=00800000
excepts=30, dbl=380fffffef000000, flt=00800000
excepts=30, dbl=380fffffee000000, flt=00800000
...
excepts=30, dbl=380fffffe1000000, flt=00800000
excepts=30, dbl=380fffffe0000000, flt=00800000  FLT_MIN * (1 - ulp/2)
excepts=30, dbl=380fffffdf000000, flt=007fffff
excepts=30, dbl=380fffffde000000, flt=007fffff
...
excepts=30, dbl=380fffffd1000000, flt=007fffff
excepts=30, dbl=380fffffd0000000, flt=007fffff
excepts=30, dbl=380fffffcf000000, flt=007fffff
excepts=30, dbl=380fffffce000000, flt=007fffff
...
excepts=30, dbl=380fffffc3000000, flt=007fffff
excepts=30, dbl=380fffffc2000000, flt=007fffff
excepts=30, dbl=380fffffc1000000, flt=007fffff
excepts=00, dbl=380fffffc0000000, flt=007fffff  Exactly FLT_MIN * ( 1 - ulp )
	
	
By powers of 2 getting closer and closer to FLT_MIN:
	
  FLT_MIN * ( 1.0 - 2.0**i )
	
excepts=00, dbl=380fffff80000000, flt=007ffffe
excepts=00, dbl=380fffffc0000000, flt=007fffff
excepts=30, dbl=380fffffe0000000, flt=00800000  Why just this one ?
excepts=20, dbl=380ffffff0000000, flt=00800000
excepts=20, dbl=380ffffff8000000, flt=00800000
excepts=20, dbl=380ffffffc000000, flt=00800000
excepts=20, dbl=380ffffffe000000, flt=00800000
excepts=20, dbl=380fffffff000000, flt=00800000
....
excepts=20, dbl=380ffffffffffff8, flt=00800000
excepts=20, dbl=380ffffffffffffc, flt=00800000
excepts=20, dbl=380ffffffffffffe, flt=00800000
excepts=20, dbl=380fffffffffffff, flt=00800000

-- 
Fred Tydeman        (512) 255-8696     Austin, Texas
Computer Consultant               tydemananetcom.com
Analysis, Design, Programming, Testing and Education
Member x3j11 ( ANSI "C" standards committee )



More information about the Numeric-interest mailing list