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