Handling Run-Time Math Exceptions (ia32 only)

On ia32 systems, the run-time subroutine MATHERRQQ (ia32 only) handles floating-point exceptions that occur in the math functions, such as SIN and LOG10.

If you use the default version of MATHERRQQ, which the linker automatically includes in your executable program, then math exceptions result in a standard run-time error (such as forrtl: severe (nnnn): sqrt: domain error). If you want to alter the behavior of one or more math exceptions, you need to provide your own version of MATHERRQQ. You have more flexibility in the way you handle run-time math exceptions than floating-point exceptions, because your error handling routine can return to the program unit that caused the exception.

The module DFLIB.F90 in the ...\DF98\INCLUDE folder contains the definitions of the run-time math exceptions. These are listed in the following table:

Parameter Name Value Description
MTH$E_DOMAIN 1 Argument domain error
MTH$E_SINGULARITY 2 Argument singularity
MTH$E_OVERFLOW 3 Overflow range error
MTH$E_UNDERFLOW 4 Underflow range error
MTH$E_TLOSS 5 Total loss of precision
MTH$E_PLOSS 6 Partial loss of precision

A domain error means that an argument is outside the math function's domain, for example, SQRT(-1). A singularity error means that an argument is a singularity value for the math function, and the result is not defined for that value, for example, LOG10(0.0). Overflow and underflow errors are the same as floating-point counterparts, and precision loss the same as floating-point inexact results.

You can write a MATHERRQQ subroutine that resolves errors generated by math functions. Your MATHERRQQ can issue a warning, assign a default value if an error occurs, or take other action. If you do not provide your own MATHERRQQ subroutine, a default MATHERRQQ provided with the floating-point library will terminate the program. The following gives an example of an alternative MATHERRQQ subroutine (in MATHERR.F90 in the .../DF98/SAMPLES/TUTORIAL folder):

 SUBROUTINE MATHERRQQ( name, length, info, retcode)
   USE DFLIB
   INTEGER(2) length, retcode
   CHARACTER(length) name
   RECORD /MTH$E_INFO/ info
   PRINT *, "Entered MATHERRQQ"
   PRINT *, "Failing function is: ", name
   PRINT *, "Error type is: ", info.errcode
   IF ((info.ftype == TY$REAL4 ).OR.(info.ftype == TY$REAL8)) THEN
       PRINT *, "Type: REAL"
       PRINT *, "Enter the desired function result: "
       READ(*,*) info.r8res
       retcode = 1
   ELSE IF ((info.ftype == TY$CMPLX8 ).OR.(info.ftype == TY$CMPLX16)) THEN
       PRINT *, "Type: COMPLEX"
       PRINT *, "Enter the desired function result: "
       READ(*,*) info.c16res
       retcode = 1
   END IF
 END

The following is a Visual Fortran Sample program (MATHTEST.F90 in the .../DF98/SAMPLES/TUTORIAL folder) that causes MATHERQQ to be called:

 REAL(4) r1, r2 /-1.0/
 REAL(8) r3, r4 /-1.0/
 COMPLEX(4) c1, c2 /(0.0, 0.0)/
 r1 = LOG(r2)
 r3 = SQRT(r4)
 c1 = CLOG(c2)

 WRITE(*, *) r1
 WRITE(*, *) r3
 WRITE(*, *) c1
 END