[comp.sys.sgi] exp

glennrp@BRL.ARPA (Glenn Randers-Pehrson, WMB) (07/07/88)

The behaviour of the EXP() function for large negative numbers on the
IRIS is shameful.  I've tried the following program on a number of
machines (VAX f77, Gould f77, Alliant FORTRAN, Cray-2 cft77) and all
return 0.0 for out-of-range negative numbers.  The IRIS returns
not-a-number if the floating point board isn't used.  Worse, if the
floating point board is used it returns wrong numbers.  This on a 3130
running 3.5r2 and a 2500T running 3.6.


      program bugexp
      dimension trial(10)
      data trial/-1., -20., -50., -80., -85., -88.02968, -88.02970,
     &           -100., -1000., -10000/
      do 10 i=1,10
      x=trial(i)
      xx=exp(x)
      write(*,'('' exp('',f13.6,'')='',g15.8)')x,xx
   10 continue
      stop
      end

Results with f77 -Zf:

 exp(    -1.000000)=  .36787950    
 exp(   -20.000000)=  .20611540E-08
 exp(   -50.000000)=  .19287500E-21
 exp(   -80.000000)=  .18048510E-34
 exp(   -85.000000)=  .12160990E-36
 exp(   -88.029680)=  .15974800E-42
 exp(   -88.029700)=???????????????
 exp(  -100.000000)= -.43075530E+34
 exp( -1000.000000)=  .12234650E+29
 exp(-10000.000000)=  .41732680E-27

 Programmed STOP 

mccalpin@MASIG1.OCEAN.FSU.EDU ("John D. McCalpin") (07/08/88)

Silicon Graphics has known about the pathetic behavior of the exp
function for a long time, but they do not seem at all interested in
doing anything about it.... As I understand it, they bought the
compiler from Silicon Valley Software, and did an in-house rewrite of
the intrinsic transcendental functions.  

The behaviour can be modified (though not corrected) by initializing
the floating-point exception handler. You will need to add the
following lines to the example code:

#include <fortfpe.h>				! somewhere in declarations

	call setfpe (NOCOREDUMP, ZEROVALS)	! first executable statement

This makes MOST underflows go gently to zero, but it does not 
fix the exp() problem. I don't know why the floating-point exception
handler is not active by default....

I have to uses a fix to the exp() problem, I use
	x = min(x,88.0)
	x = max(-88.0,x)
	result=exp(x)
or, in one line:
	result = exp(max(-88.0,min(x,88.0)))
The constant 88.0 is the largest value which returns a correct result
with 32-bit precision. I can't recall the number for 64-bit precision
--- I think it is about 300.

Now that the 4D's are the SGI's main interest, I would not count on
getting any improvements to the SVS Fortran on the IRIS 3000's....
especially since they did not respond when the IRIS 3000 was their 
only entry.  I suggest that you try a SUN machine.  They have troubles, 
but at least the Fortran numerics are quite robust.

John D. McCalpin
mccalpin@nu.cs.fsu.edu