IEEE arithmetic is a relatively new way of dealing with arithmetic operations that result in such problems as invalid, division by zero, overflow, underflow, or inexact. The differences are in rounding, handling numbers near zero, and handling numbers near the machine maximum.
The IEEE standard supports user handling of exceptions, rounding, and precision. Consequently, the standard supports interval arithmetic and diagnosis of anomalies. IEEE Standard 754 makes it possible to standardize elementary functions like exp and cos, to create high precision arithmetic, and to couple numerical and symbolic algebraic computation.
IEEE arithmetic offers users greater control over computation than does any other kind of floating-point arithmetic. The standard simplifies the task of writing numerically sophisticated, portable programs. Many questions about floating-point arithmetic concern elementary operations on numbers. For example:
What is the result of an operation when the infinitely precise result is not representable in the computer hardware?
Are elementary operations like multiplication and addition commutative?
Another class of questions concerns floating-point exceptions and exception handling. What happens if you:
Multiply two very large numbers with the same sign?
Divide nonzero by zero?
Divide zero by zero?
In older arithmetic models, the first class of questions might not have the expected answers, while the exceptional cases in the second class might all have the same result: the program aborts on the spot or proceeds with garbage results.
The standard ensures that operations yield the mathematically expected results with the expected properties. It also ensures that exceptional cases yield specified results, unless the user specifically makes other choices.
For example, the exceptional values +Inf, -Inf, and NaN are introduced intuitively:
big*big = +Inf Positive infinity big*(-big) = -Inf Negative infinity num/0.0 = +Inf Where num > 0.0 num/0.0 = -Inf Where num < 0.0 0.0/0.0 = NaN Not a Number
Also, five types of floating-point exception are identified:
Invalid. Operations with mathematically invalid operands--for example, 0.0/0.0, sqrt(-1.0), and log(-37.8)
Division by zero. Divisor is zero and dividend is a finite nonzero number--for example, 9.9/0.0
Overflow. Operation produces a result that exceeds the range of the exponent-- for example, MAXDOUBLE+0.0000000000001e308
Underflow. Operation produces a result that is too small to be represented as a normal number--for example, MINDOUBLE * MINDOUBLE
Inexact. Operation produces a result that cannot be represented with infinite precision--for example, 2.0 / 3.0, log(1.1) and 0.1 in input
The implementation of the IEEE standard is described in the Sun Numerical Computation Guide.
The -ftrap=mode option enables trapping for floating-point exceptions. If no signal handler has been established by an ieee_handler() call, the exception terminates the program with a memory dump core file. See Fortran User's Guide for details on this compiler option. For example, to enable trapping for overflow, division by zero, and invalid operations, compile with -ftrap=common.
You must compile the application's main program with -ftrap= for trapping to be enabled.
Programs compiled by f77 automatically display a list of accrued floating-point exceptions on program termination. In general, a message results if any one of the invalid, division-by-zero, or overflow exceptions have occurred. Inexact exceptions do not generate messages because they occur so frequently in real programs.
f90 programs do not automatically report on exceptions at program termination. An explicit call to ieee_retrospective(3M) is required.
You can turn off any or all of these messages with ieee_flags() by clearing exception status flags. Do this at the end of your program.
Exception handling according to the IEEE standard is the default on SPARC and x86 processors. However, there is a difference between detecting a floating-point exception and generating a signal for a floating-point exception (SIGFPE).
Following the IEEE standard, two things happen when an untrapped exception occurs during a floating-point operation:
The system returns a default result. For example, on 0/0 (invalid), the system returns NaN as the result.
A flag is set to indicate that an exception is raised. For example, 0/0 (invalid), the system sets the "invalid operation" flag.
f77 and f90 differ significantly in the way they handle floating-point exceptions.
With f77, the default on SPARC and x86 systems is not to automatically generate a signal to interrupt the running program for a floating-point exception. The assumptions are that signals could degrade performance and that most exceptions are not significant as long as expected values are returned.
The default with f90 is to automatically trap on division by zero, overflow, and invalid operation.
The f77 and f90 command-line option -ftrap can be used to change the default. In terms of -ftrap, the default for f77 is -ftrap=%none. The default for f90 is -ftrap=common.
To enable exception trapping, compile the main program with one of the -ftrap options--for example: -ftrap=common.
One aspect of standard IEEE arithmetic, called gradual underflow, can be manually disabled. When disabled, the program is considered to be running with nonstandard arithmetic.
The IEEE standard for arithmetic specifies a way of handling underflowed results gradually by dynamically adjusting the radix point of the significand. In IEEE floating-point format, the radix point occurs before the significand, and there is an implicit leading bit of 1. Gradual underflow allows the implicit leading bit to be cleared to 0 and shifts the radix point into the significant when the result of a floating-point computation would otherwise underflow. With a SPARC processor this result is not accomplished in hardware but in software. If your program generates many underflows (perhaps a sign of a problem with your algorithm) and you run on a SPARC processor, you may experience a performance loss.
Gradual underflow can be disabled either by compiling with the -fns option or by calling the library routine nonstandard_arithmetic() from within the program to turn it off. Call standard_arithmetic() to turn gradual underflow back on.
To be effective, the application's main program must be compiled with -fns. See the Fortran User's Guide.
For legacy applications, take note that:
The standard_arithmetic() subroutine replaces an earlier routine named gradual_underflow().
The nonstandard_arithmetic() subroutine replaces an earlier routine named abrupt_underflow().
The -fns option and the nonstandard_arithmetic() library routine are effective only on some SPARC systems. On x86 platforms, gradual underflow is performed by the hardware.