This section describes the IEEE recommended functions, the functions that supply useful values, ieee_flags, ieee_retrospective, and standard_arithmetic and nonstandard_arithmetic. Refer to Exceptions and Exception Handling for more information on the functions ieee_flags and ieee_handler.
The functions described by ieee_functions(3m) and ieee_sun(3m) provide capabilities either required by the IEEE standard or recommended in its appendix. These are implemented as efficient bit mask operations.
|
|
The remainder(x,y) is the operation specified in IEEE Standard 754-1985. The difference between remainder(x,y) and fmod(x,y) is that the sign of the result returned by remainder(x,y) might not agree with the sign of either x or y, whereas fmod(x,y) always returns a result whose sign agrees with x. Both functions return exact results and do not generate inexact exceptions.
|
|
IEEE values like infinity, NaN, maximum and minimum positive floating-point numbers are provided by the functions described by the ieee_values(3m) man page. Table 22, Table 23, Table 24, and Table 25 show the decimal values and hexadecimal IEEE representations of the values provided by ieee_values(3m) functions.
|
|
|
|
ieee_flags (3m) is the Oracle interface to:
The syntax for a call to ieee_flags(3m) is:
i = ieee_flags(action, mode, in, out);
The ASCII strings that are the possible values for the parameters are shown in Table 26:
|
The ieee_flags(3m) man page describes the parameters in complete detail.
Some of the arithmetic features that can be modified by using ieee_flags are covered in the following paragraphs. Chapter 4 contains more information on ieee_flags and IEEE exception flags.
When mode is direction, the specified action applies to the current rounding direction. The possible rounding directions are: round towards nearest, round towards zero, round towards +•, or round towards -•. The IEEE default rounding direction is round towards nearest. This means that when the mathematical result of an operation lies strictly between two adjacent representable numbers, the one nearest to the mathematical result is delivered. (If the mathematical result lies exactly halfway between the two nearest representable numbers, then the result delivered is the one whose least significant bit is zero. The round towards nearest mode is sometimes called round to nearest even to emphasize this.)
Rounding towards zero is the way many pre-IEEE computers work, and corresponds mathematically to truncating the result. For example, if 2/3 is rounded to 6 decimal digits, the result is .666667 when the rounding mode is round towards nearest, but .666666 when the rounding mode is round towards zero.
When using ieee_flags to examine, clear, or set the rounding direction, possible values for the four input parameters are shown in Table 27.
|
When mode is precision, the specified action applies to the current rounding precision. On x86-based systems, the possible rounding precisions are: single, double, and extended. The default rounding precision is extended; in this mode, arithmetic operations that deliver a result to an x87 floating-point register round their result to the full 64-bit precision of the extended double register format. When the rounding precision is single or double, arithmetic operations that deliver a result to an x87 floating-point register round their result to 24 or 53 significant bits, respectively. Although most programs produce results that are at least as accurate, if not more so, when extended rounding precision is used, some programs that require strict adherence to the semantics of IEEE arithmetic will not work correctly in extended rounding precision mode and must be run with the rounding precision set to single or double as appropriate.
Rounding precision cannot be set on systems using SPARC processors. On these systems, calling ieee_flags with mode = precision has no effect on computation.
Finally, when mode is exception, the specified action applies to the current IEEE exception flags. See Exceptions and Exception Handling for more information about using ieee_flags to examine and control the IEEE exception flags.
The libsunmath function ieee_retrospective prints information about unrequited exceptions and nonstandard IEEE modes. It reports:
The necessary information is obtained from the hardware floating-point status register.
ieee_retrospective prints information about exception flags that are raised, and exceptions for which a trap is enabled. These two distinct, if related, pieces of information should not be confused. If an exception flag is raised, then that exception occurred at some point during program execution. If a trap is enabled for an exception, then the exception might not have actually occurred, but if it had, a SIGFPE signal would have been delivered. The ieee_retrospective message is meant to alert you about exceptions that might need to be investigated, if the exception flag is raised, or to remind you that exceptions might have been handled by a signal handler, if the exception's trap is enabled. Exceptions and Exception Handling discusses exceptions, signals, and traps, and shows how to investigate the cause of a raised exception.
A program can explicitly call ieee_retrospective at any time. Fortran programs compiled with f95 in –f77 compatibility mode automatically call ieee_retrospective before they exit. C/C++ programs and Fortran programs compiled with f95 in the default mode do not automatically call ieee_retrospective.
Note, though, that the f95 compiler enables trapping on common exceptions by default, so unless a program either explicitly disables trapping or installs a SIGFPE handler, it will immediately abort when such an exception occurs. In –f77 compatibility mode, the compiler does not enable trapping, so when floating-point exceptions occur, the program continues execution and reports those exceptions via the ieee_retrospective output on exit.
The syntax for calling this function is as follows:
C, C++ - ieee_retrospective(fp);
Fortran - call ieee_retrospective()
For the C function, the argument fp specifies the file to which the output will be written. The Fortran function always prints output on stderr.
The following example shows four of the six ieee_retrospective warning messages:
Note: IEEE floating-point exception flags raised: Inexact; Underflow; Rounding direction toward zero IEEE floating-point exception traps enabled: overflow; See the Numerical Computation Guide, ieee_flags(3M), ieee_handler(3M), ieee_sun(3m)
A warning message appears only if trapping is enabled or an exception was raised.
You can suppress ieee_retrospective messages from Fortran programs by one of three methods. One approach is to clear all outstanding exceptions, disable traps, and restore round-to-nearest, extended precision, and standard modes before the program exits. To do this, call ieee_flags, ieee_handler, and standard_arithmetic as follows:
character*8 out i = ieee_flags('clearall', '', '', out) call ieee_handler('clear', 'all', 0) call standard_arithmetic()
Another way to avoid seeing ieee_retrospective messages is to redirect stderr to a file. Of course, this method should not be used if the program sends output other than ieee_retrospective messages to stderr.
The third approach is to include a dummy ieee_retrospective function in the program, for example:
subroutine ieee_retrospective return end
As discussed in IEEE Arithmetic, IEEE arithmetic handles underflowed results using gradual underflow. On some SPARC-based systems, gradual underflow is often implemented partly with software emulation of the arithmetic. If many calculations underflow, this can cause performance degradation.
To obtain some information about whether this is a case in a specific program, you can use ieee_retrospective or ieee_flags to determine if underflow exceptions occur, and check the amount of system time used by the program. If a program spends an unusually large amount of time in the operating system, and raises underflow exceptions, gradual underflow might be the cause. In this case, using non-IEEE arithmetic might speed up program execution.
The function nonstandard_arithmetic enables non-IEEE arithmetic modes on processors that support them. On SPARC systems, this function sets the NS (nonstandard arithmetic) bit in the floating-point status register. On x86 systems supporting the SSE instructions, this function sets the FTZ (flush to zero) bit in the MXCSR register; it also sets the DAZ (denormals are zero) bit in the MXCSR register on those processors that support this bit. Note that the effects of nonstandard modes vary from one processor to another and can cause otherwise robust software to malfunction. Nonstandard mode is not recommended for normal use.
The function standard_arithmetic resets the hardware to use the default IEEE arithmetic. Both functions have no effect on processors that provide only the default IEEE 754 style of arithmetic. SPARC T4 is one such processor.