XL Fortran offers support for IEEE floating-point functionality as specified in the Fortran 2003 standard. The standard defines the IEEE_EXCEPTIONS module for exceptions, the IEEE_ARITHMETIC module to support IEEE arithmetic, and IEEE_FEATURES to specify the IEEE features supported by the compiler.
When using the IEEE_EXCEPTIONS, or IEEE_ARITHMETIC intrinsic modules, the XL Fortran compiler enforces several Fortran 2003 standard rules regarding the scope of changes to the floating-point status concerning rounding mode, halting mode, and exception flags. This can impede the performance of programs that use these modules, but do not utilize the new floating-point status semantics. For such programs, the -qstrictieeemod compiler option is provided to relax the rules on saving and restoring floating point status.
XL Fortran provides a number of options for strict compliance with the IEEE standard.
For more information on IEEE floating-point and specific explanations of the compiler options listed above, see Implementation details of XL Fortran floating-point processing.
The IEEE_ARITHMETIC, IEEE_EXCEPTIONS, and IEEE_FEATURES modules are intrinsic, though the types and procedures defined in these modules are not intrinsic.
All functions contained in IEEE modules are pure.
All procedure names are generic and not specific.
The default value for all exception flags is quiet.
By default, exceptions do not cause halting.
Rounding mode defaults towards nearest.
The IEEE modules define the following derived types.
A derived data type defined by the IEEE_EXCEPTIONS module that identifies a particular exception flag. The values for IEEE_FLAG_TYPE must be one of the following named constants as defined in the IEEE_EXCEPTIONS module:
When using REAL(4), an overflow occurs when the result value's unbiased exponent is > 127 or < -126.
When using REAL(8), an overflow occurs when the result value's unbiased exponent is > 1023 or < -1022.
For REAL(4), an underflow occurs when the result has an absolute value < 2-149.
For REAL(8), an underflow occurs when the result has an absolute value < 2-1074.
The following constants are arrays of IEEE_FLAG_TYPE:
A derived data type defined in the IEEE_ARITHMETIC module that represents the current floating-point status. The floating-point status encompasses the values of all exception flags, halting, and rounding modes.
A derived data type defined in the IEEE_ARITHMETIC module that categorizes a class of floating-point values. The values for IEEE_CLASS_TYPE must be one of the following named constants as defined in the IEEE_ARITHMETIC module:
IEEE_SIGNALING_NAN | IEEE_NEGATIVE_ZERO |
IEEE_QUIET_NAN | IEEE_POSITIVE_ZERO |
IEEE_NEGATIVE_INF | IEEE_POSITIVE_DENORMAL |
IEEE_NEGATIVE_NORMAL | IEEE_POSITIVE_NORMAL |
IEEE_NEGATIVE_DENORMAL | IEEE_POSITIVE_INF |
A derived data type defined in the IEEE_ARITHMETIC module that identifies a particular rounding mode. The values for IEEE_ROUND_TYPE must be one of the following named constants as defined in the IEEE_ARITHMETIC module:
A derived data type defined in the IEEE_FEATURES module that identifies the IEEE features to use. The values for IEEE_FEATURES_TYPE must be one of the following named constants as defined in the IEEE_FEATURES module:
IEEE_DATATYPE | IEEE_DATATYPE |
IEEE_DENORMAL | IEEE_INVALID_FLAG |
IEEE_DIVIDE | IEEE_NAN |
IEEE_HALTING | IEEE_ROUNDING |
IEEE_INEXACT_FLAG | IEEE_SQRT |
IEEE_INF | IEEE_UNDERFLOW_FLAG |
The IEEE_ARITHMETIC module defines two sets of elemental operators for comparing variables of IEEE_CLASS_TYPE or IEEE_ROUND_TYPE.
To use the following IEEE procedures, you must add a USE IEEE_ARITHMETIC, USE IEEE_EXCEPTIONS, or USE IEEE_FEATURES statement to your source file as required. For more information on the USE statement, see USE.
XL Fortran supports all the named constants in the IEEE_FEATURES module.
The IEEE_ARITHMETIC module behaves as if it contained a USE statement for IEEE_EXCEPTIONS. All values that are public in IEEE_EXCEPTIONS remain public in IEEE_ARITHMETIC.
When the IEEE_EXCEPTIONS or the IEEE_ARITHMETIC modules are accessible, IEEE_OVERFLOW and IEEE_DIVIDE_BY_ZERO are supported in the scoping unit for all kinds of real and complex data. To determine the other exceptions supported use the IEEE_SUPPORT_FLAG function. Use IEEE_SUPPORT_HALTING to determine if halting is supported. Support of other exceptions is influenced by the accessibility of the named constants IEEE_INEXACT_FLAG, IEEE_INVALID_FLAG, and IEEE_UNDERFLOW_FLAG of the IEEE_FEATURES module as follows:
If an exception flag signals on entry to a scoping unit that does not access IEEE_EXCEPTIONS or IEEE_ARITHMETIC, the compiler ensures that the exception flag is signaling on exit. If a flag is quiet on entry to such a scoping unit, it can be signaling on exit.
Further IEEE support is available through the IEEE_ARITHMETIC module. Support is influenced by the accessibility of named constants in the IEEE_FEATURES module:
If the IEEE_EXCEPTIONS or IEEE_ARITHMETIC modules are accessed, and IEEE_FEATURES is not, the supported subset of features is the same as if IEEE_FEATURES was accessed.
An elemental IEEE class function. Returns the IEEE class of a floating-point value.
IEEE_ARITHMETIC
Where X is of type real.
The result is of type IEEE_CLASS_TYPE.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) function must return with a value of true. If you specify a data type of REAL(16), then IEEE_SUPPORT_DATATYPE will return false, though the appropriate class type will still be returned.
USE, INTRINSIC :: IEEE_ARITHMETIC TYPE(IEEE_CLASS_TYPE) :: C REAL :: X = -1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN C = IEEE_CLASS(X) ! C has class IEEE_NEGATIVE_NORMAL ENDIF
An elemental IEEE copy sign function. Returns the value of X with the sign of Y.
IEEE_ARITHMETIC
Where X and Y are of type real, though they may be of different kinds.
The result is of the same kind and type as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_DATATYPE(Y) must return with a value of true.
For supported IEEE special values, such as NaN and infinity, IEEE_COPY_SIGN returns the value of X with the sign of Y.
IEEE_COPY_SIGN ignores the -qxlf90=nosignedzero compiler option.
Example 1:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X DOUBLE PRECISION :: Y X = 3.0 Y = -2.0 IF (IEEE_SUPPORT_DATATYPE(X) .AND. IEEE_SUPPORT_DATATYPE(Y)) THEN X = IEEE_COPY_SIGN(X,Y) ! X has value -3.0 ENDIF
Example 2:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X, Y Y = 1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN X = IEEE_VALUE(X, IEEE_NEGATIVE_INF) ! X has value -inf X = IEEE_COPY_SIGN(X,Y) ! X has value +inf ENDIF
An elemental IEEE subroutine. Retrieves the status of the exception flag specified. Sets FLAG_VALUE to true if the flag is signaling, or false otherwise.
IEEE_ARITHMETIC
Where FLAG is an INTENT(IN) argument of type IEEE_FLAG_TYPE specifying the IEEE flag to obtain. FLAG_VALUE is an INTENT(OUT) default logical argument that contains the value of FLAG.
USE, INTRINSIC:: IEEE_EXCEPTIONS LOGICAL :: FLAG_VALUE CALL IEEE_GET_FLAG(IEEE_OVERFLOW,FLAG_VALUE) IF (FLAG_VALUE) THEN PRINT *, "Overflow flag is signaling." ELSE PRINT *, "Overflow flag is quiet." ENDIF
An elemental IEEE subroutine. Retrieves the halting mode for an exception and sets HALTING to true if the exception specified by the flag will cause halting.
IEEE_ARITHMETIC
Where FLAG is an INTENT(IN) argument of type IEEE_FLAG_TYPE specifying the IEEE flag. HALTING is an INTENT(OUT) default logical.
USE, INTRINSIC :: IEEE_EXCEPTIONS LOGICAL HALTING CALL IEEE_GET_HALTING_MODE(IEEE_OVERFLOW,HALTING) IF (HALTING) THEN PRINT *, "The program will halt on an overflow exception." ENDIF
An IEEE subroutine. Sets ROUND_VALUE to the current IEEE rounding mode.
IEEE_ARITHMETIC
Where ROUND_VALUE is an INTENT(OUT) scalar of type IEEE_ROUND_TYPE.
USE, INTRINSIC :: IEEE_ARITHMETIC TYPE(IEEE_ROUND_TYPE) ROUND_VALUE CALL IEEE_GET_ROUNDING_MODE(ROUND_VALUE) ! Store the rounding mode IF (ROUND_VALUE == IEEE_OTHER) THEN PRINT *, "You are not using an IEEE rounding mode." ENDIF
An IEEE subroutine. Retrieves the current IEEE floating-point status.
IEEE_ARITHMETIC
Where STATUS_VALUE is an INTENT(OUT) scalar of type IEEE_STATUS_TYPE.
You can only use STATUS_VALUE in an IEEE_SET_STATUS invocation.
USE, INTRINSIC :: IEEE_ARITHMETIC TYPE(IEEE_STATUS_TYPE) STATUS_VALUE ... CALL IEEE_GET_STATUS(STATUS_VALUE) ! Get status of all exception flags CALL IEEE_SET_FLAG(IEEE_ALL,.FALSE.) ! Set all exception flags to quiet ... ! calculation involving exception handling CALL IEEE_SET_STATUS(STATUS_VALUE) ! Restore the flags
An elemental IEEE function. Tests whether a value is finite. Returns true if IEEE_CLASS(X) has one of the following values:
It returns false otherwise.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X = 1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN PRINT *, IEEE_IS_FINITE(X) ! Prints true ENDIF
An elemental IEEE function. Tests whether a value is IEEE Not-a-Number. Returns true if IEEE_CLASS(X) has the value IEEE_SIGNALING_NAN or IEEE_QUIET_NAN. It returns false otherwise.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_NAN(X) must return with a value of true.
Example 1:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X = -1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN IF (IEEE_SUPPORT_SQRT(X)) THEN ! IEEE-compliant SQRT function IF (IEEE_SUPPORT_NAN(X)) THEN PRINT *, IEEE_IS_NAN(SQRT(X)) ! Prints true ENDIF ENDIF ENDIF
Example 2:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X = -1.0 IF (IEEE_SUPPORT_STANDARD(X)) THEN PRINT *, IEEE_IS_NAN(SQRT(X)) ! Prints true ENDIF
An elemental IEEE function. Tests whether a value is negative. Returns true if IEEE_CLASS(X) has one of the following values:
It returns false otherwise.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(1.0)) THEN PRINT *, IEEE_IS_NEGATIVE(1.0) ! Prints false ENDIF
An elemental IEEE function. Tests whether a value is normal. Returns true if IEEE_CLASS(X) has one of the following values:
It returns false otherwise.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X = -1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN IF (IEEE_SUPPORT_SQRT(X)) THEN ! IEEE-compliant SQRT function PRINT *, IEEE_IS_NORMAL(SQRT(X)) ! Prints false ENDIF ENDIF
An elemental IEEE function. Returns unbiased exponent in the IEEE floating-point format. If the value of X is neither zero, infinity, or NaN, the result has the value of the unbiased exponent of X, equal to EXPONENT(X)-1.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is the same type and kind as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X is zero, the result is negative infinity.
If X is infinite, the result is positive infinity.
If X is NaN, the result is nan.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(1.1)) THEN PRINT *, IEEE_LOGB(1.1) ! Prints 0.0 ENDIF
An elemental IEEE function. Returns the next machine-representable neighbor of X in the direction towards Y.
IEEE_ARITHMETIC
Where X and Y are of type real.
Where the result is the same type and kind as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_DATATYPE(Y) must return with a value of true.
If X and Y are equal the function returns X without signaling an exception. If X and Y are not equal, the function returns the next machine-representable neighbor of X in the direction towards Y.
The neighbors of zero, of either sign, are both nonzero.
IEEE_OVERFLOW and IEEE_INEXACT are signaled when X is finite but IEEE_NEXT_AFTER(X, Y) is infinite.
IEEE_UNDERFLOW and IEEE_INEXACT are signaled when IEEE_NEXT_AFTER(X, Y) is denormalized or zero.
If X or Y is a quiet NaN, the result is one of the input NaN values.
Example 1:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X = 1.0, Y = 2.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN PRINT *, (IEEE_NEXT_AFTER(X,Y) == X + EPSILON(X)) ! Prints true ENDIF
Example 2:
USE, INTRINSIC :: IEEE_ARITHMETIC REAL(4) :: X = 0.0, Y = 1.0 IF (IEEE_SUPPORT_DATATYPE(X)) THEN PRINT *, (IEEE_NEXT_AFTER(X,Y) == 2.0**(-149)) ! Prints true ENDIF
An elemental IEEE remainder function. The result value, regardless of the rounding mode, is exactly X-Y*N, where N is the integer nearest to the exact value X/Y; whenever |N - X/Y| = 1/2, N is even.
IEEE_ARITHMETIC
Where X and Y are of type real.
Where the result is of type real with the same kind as the argument with greater precision.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_DATATYPE(Y) must return with a value of true.
If the result value is zero, the sign is the same as X.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(4.0)) THEN PRINT *, IEEE_REM(4.0,3.0) ! Prints 1.0 PRINT *, IEEE_REM(3.0,2.0) ! Prints -1.0 PRINT *, IEEE_REM(5.0,2.0) ! Prints 1.0 ENDIF
An elemental IEEE function. Rounds to an integer value according to the current rounding mode.
IEEE_ARITHMETIC
Where X is of type real.
Where the result is the same type and kind as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If the result has the value zero, the sign is that of X.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(1.1)) THEN CALL IEEE_SET_ROUNDING_MODE(IEEE_NEAREST) PRINT *, IEEE_RINT(1.1) ! Prints 1.0 CALL IEEE_SET_ROUNDING_MODE(IEEE_UP) PRINT *, IEEE_RINT(1.1) ! Prints 2.0 ENDIF
An elemental IEEE function. Returns X * 2I.
IEEE_ARITHMETIC
Where X is of type real and I is of type INTEGER.
Where the result is the same type and kind as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X * 2I is representable as a normal number, then the result is a normal number.
If X is finite and X * 2I is too large the IEEE_OVERFLOW exception occurs. The result value is infinity with the sign of X.
If X * 2I is too small and there is a loss of accuracy, the IEEE_UNDERFLOW exception occurs. The result is the nearest representable number with the sign of X.
If X is infinite, the result is the same as X with no exception signals.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(1.0)) THEN PRINT *, IEEE_SCALB(1.0,2) ! Prints 4.0 ENDIF
A transformational IEEE function. Returns a value of the kind type parameter of an IEEE real data type with decimal precision of at least P digits, and a decimal exponent range of at least R.
IEEE_ARITHMETIC
Where P and R are both scalar optional arguments of type integer.
If the kind type parameter is not available and the precision is not available, the result is -1. If the kind type parameter is not available and the exponent range is not available, the result is -2. If the kind type parameter is not available and if neither the precision or the exponent range is available, the result is -3.
If more than one kind type parameter value is applicable, the value returned is the one with the smallest decimal precision. If there are several values, the smallest of these kind values is returned.
USE, INTRINSIC :: IEEE_ARITHMETIC ! P and R fit in a real(4) PRINT *, IEEE_SELECTED_REAL_KIND(6,37) ! prints 4 ! P needs at least a real(8) PRINT *, IEEE_SELECTED_REAL_KIND(14,37) ! prints 8 ! R needs at least a real(8) PRINT *, IEEE_SELECTED_REAL_KIND(6,307) ! prints 8 ! P is too large PRINT *, IEEE_SELECTED_REAL_KIND(40,37) ! prints -1 ! R is too large PRINT *, IEEE_SELECTED_REAL_KIND(6,400) ! prints -2 ! P and R are both too large PRINT *, IEEE_SELECTED_REAL_KIND(40,400) ! prints -3 END
An IEEE subroutine. Assigns a value to an IEEE exception flag.
IEEE_EXCEPTIONS
Where FLAG is an INTENT(IN) scalar or array argument of type IEEE_FLAG_TYPE corresponding to the value of the flag to be set. FLAG_VALUE is an INTENT(IN) scalar or array argument of type logical, corresponding to the desired status of the exception flag. The value of FLAG_VALUE should be conformable with the value of FLAG.
If FLAG_VALUE is true, the exception flag specified by FLAG is set to signaling. Otherwise, the flag is set to quiet.
Each element of FLAG must have a unique value.
USE, INTRINSIC :: IEEE_EXCEPTIONS CALL IEEE_SET_FLAG(IEEE_OVERFLOW, .TRUE.) ! IEEE_OVERFLOW is now signaling
An IEEE subroutine. Controls continuation or halting after an exception.
IEEE_EXCEPTIONS
Where FLAG is an INTENT(IN) scalar or array argument of type IEEE_FLAG_TYPE corresponding to the exception flag for which holding applies. HALTING is an INTENT(IN) scalar or array argument of type logical, corresponding to the desired halting status. By default exceptions will not cause halting in XL Fortran. The value of HALTING should be conformable with the value of FLAG.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If HALTING is true, the exception specified by FLAG will cause halting. Otherwise, execution will continue after the exception.
Each element of FLAG must have a unique value.
@PROCESS FLOAT(NOFOLD) USE, INTRINSIC :: IEEE_EXCEPTIONS REAL :: X CALL IEEE_SET_HALTING_MODE(IEEE_DIVIDE_BY_ZERO, .TRUE.) X = 1.0 / 0.0 ! Program will halt with a divide-by-zero exception
An IEEE subroutine. Sets the current rounding mode.
IEEE_ARITHMETIC
Where ROUND_VALUE is an INTENT(IN) argument of type IEEE_ROUND_TYPE specifying the rounding mode.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_ROUNDING (ROUND_VALUE, X) must return with a value of true.
The compilation unit calling this program must be compiled with the -qfloat=rrm compiler option.
All compilation units calling programs compiled with the -qfloat=rrm compiler option must also be compiled with this option.
USE, INTRINSIC :: IEEE_ARITHMETIC IF (IEEE_SUPPORT_DATATYPE(1.1)) THEN CALL IEEE_SET_ROUNDING_MODE(IEEE_NEAREST) PRINT *, IEEE_RINT(1.1) ! Prints 1.0 CALL IEEE_SET_ROUNDING_MODE(IEEE_UP) PRINT *, IEEE_RINT(1.1) ! Prints 2.0 ENDIF
An IEEE subroutine. Restores the value of the floating-point status.
IEEE_ARITHMETIC
Where STATUS_VALUE is an INTENT(IN) argument of type IEEE_STATUS_TYPE specifying the floating-point status.
STATUS_VALUE must have been set previously by IEEE_GET_STATUS.
An inquiry IEEE function. Determines whether the current implementation supports IEEE arithmetic. Support means using an IEEE data format and performing the binary operations of +, -, and * as in the IEEE standard whenever the operands and result all have normal values.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
If X is absent, the function returns a value of false.
If X is present and REAL(16), the function returns a value of false. Otherwise the function returns true.
USE, INTRINSIC :: IEEE_ARITHMETIC TYPE(IEEE_STATUS_TYPE) STATUS_VALUE ... CALL IEEE_GET_STATUS(STATUS_VALUE) ! Get status of all exception flags CALL IEEE_SET_FLAG(IEEE_ALL,.FALSE.) ! Set all exception flags to quiet ... ! calculation involving exception handling CALL IEEE_SET_STATUS(STATUS_VALUE) ! Restore the flags
An inquiry IEEE function. Determines whether the current implementation supports denormalized numbers.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
The result has a value of true if the implementation supports arithmetic operations and assignments with denormalized numbers for all arguments of type real where X is absent, or for real variables of the same kind type parameter as X. Otherwise, the result has a value of false.
An inquiry IEEE function. Determines whether the current implementation supports division to the accuracy of the IEEE standard.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
The result has a value of true if the implementation supports division with the accuracy specified by the IEEE standard for all arguments of type real where X is absent, or for real variables of the same kind type parameter as X. Otherwise, the result has a value of false.
An inquiry IEEE function. Determines whether the current implementation supports an exception.
IEEE_EXCEPTIONS
Where FLAG is a scalar argument of IEEE_FLAG_TYPE. X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
The result has a value of true if the implementation supports detection of the exception specified for all arguments of type real where X is absent, or for real variables of the same kind type parameter as X. Otherwise, the result has a value of false.
If X is absent, the result has a value of false.
If X is present and of type REAL(16), the result has a value of false. Otherwise the result has a value of true.
An inquiry IEEE function. Determines whether the current implementation supports the ability to abort or continue execution after an exception occurs. Support by the current implementation includes the ability to change the halting mode using IEEE_SET_HALTING(FLAG).
IEEE_EXCEPTIONS
Where FLAG is an INTENT(IN) argument of IEEE_FLAG_TYPE.
The result is a scalar of type default logical.
The result returns with a value of true for all flags.
An inquiry IEEE function. Support indicates that IEEE infinity behavior for unary and binary operations, including those defined by intrinsic functions and by functions in intrinsic modules, complies with the IEEE standard.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
The result has a value of true if the implementation supports IEEE positive and negative infinities for all arguments of type real where X is absent, or for real variables of the same kind type parameter as X. Otherwise, the result has a value of false.
If X is of type REAL(16), the result has a value of false. Otherwise the result has a value of true.
An inquiry IEEE function. Determines whether the current implementation supports IEEE base conversion rounding during formatted input/output. Support refers the ability to do IEEE base conversion during formatted input/output as described in the IEEE standard for the modes IEEE_UP, IEEE_DOWN, IEEE_ZERO, and IEEE_NEAREST for all arguments of type real where X is absent, or for real variables of the same kind type parameter as X.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X is present and of type REAL(16), the result has a value of false. Otherwise, the result returns a value of true.
An inquiry IEEE function. Determines whether the current implementation supports the IEEE Not-a-Number facility. Support indicates that IEEE NaN behavior for unary and binary operations, including those defined by intrinsic functions and by functions in intrinsic modules, conforms to the IEEE standard.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X is absent, the result has a value of false.
If X is present and of type REAL(16), the result has a value of false. Otherwise the result returns a value of true.
An inquiry IEEE function. Determines whether the current implementation supports a particular rounding mode for arguments of type real. Support indicates the ability to change the rounding mode using IEEE_SET_ROUNDING_MODE.
IEEE_ARITHMETIC
Where ROUND_VALUE is a scalar argument of IEEE_ROUND_TYPE. X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X is absent, the result has a value of true if the implementation supports the rounding mode defined by ROUND_VALUE for all arguments of type real. Otherwise, it has a value of false.
If X is present, the result returns a value of true if the implementation supports the rounding mode defined by ROUND_VALUE for real variables of the same kind type parameter as X. Otherwise, the result has a value of false.
If X is present and of type REAL(16), the result returns a value of false when ROUND_VALUE has a value of IEEE_NEAREST. Otherwise the result returns a value of true.
If ROUND_VALUE has a value of IEEE_OTHER the result has a value of false.
An inquiry IEEE function. Determines whether the current implementation supports the SQRT as defined by the IEEE standard.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
If X is absent, the result returns a value of true if SQRT adheres to IEEE conventions for all variables of type REAL. Otherwise, the result has a value of false.
If X is present, the result returns a value of true if SQRT adheres to IEEE conventions for all variables of type REAL with the same kind type parameter as X. Otherwise, the result has a value of false.
If X is present and of type REAL(16), the result has a value of false. Otherwise the result returns a value of true.
An inquiry IEEE function. Determines whether all facilities defined in the Fortran 2003 standard are supported.
IEEE_ARITHMETIC
Where X is a scalar or array valued argument of type real.
The result is a scalar of type default logical.
If X is absent, the result returns a value of false since XL Fortran supports REAL(16).
If X is present, the result returns a value of true if the following functions also return true:
Otherwise, the result returns a value of false.
An elemental IEEE unordered function.
IEEE_ARITHMETIC
Where X and Y are of type real.
The result is of type default logical.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) and IEEE_SUPPORT_DATATYPE(Y) must return with a value of true.
Unordered function that returns with a value of true if X or Y is a NaN. Otherwise the function returns with a value of false.
USE, INTRINSIC :: IEEE_ARITHMETIC REAL X, Y X = 0.0 Y = IEEE_VALUE(Y, IEEE_QUIET_NAN) PRINT *, IEEE_UNORDERED(X,Y) ! Prints true END
An elemental IEEE function. Generates an IEEE value as specified by CLASS.
IEEE_ARITHMETIC
Where X is of type real. CLASS is of type IEEE_CLASS_TYPE.
The result is of the same type and kind as X.
To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.
IEEE_SUPPORT_NAN(X) must be true if the value of CLASS is IEEE_SIGNALING_NAN or IEEE_QUIET_NAN.
IEEE_SUPPORT_INF(X) must be true if the value of CLASS is IEEE_NEGATIVE_INF or IEEE_POSITIVE_INF.
IEEE_SUPPORT_DENORMAL(X) must be true if the value of CLASS is IEEE_NEGATIVE_DENORMAL or IEEE_POSITIVE_DENORMAL.
Multiple calls of IEEE_VALUE(X, CLASS) return the same result for a particular value of X, if kind type parameter and CLASS remain the same.
If a compilation unit calls this program with a CLASS value of IEEE_SIGNALING_NAN, the compilation unit must be compiled with the -qfloat=nans compiler option.
USE, INTRINSIC :: IEEE_ARITHMETIC REAL :: X IF (IEEE_SUPPORT_DATATYPE(X)) THEN X = IEEE_VALUE(X, IEEE_NEGATIVE_INF) PRINT *, X ! Prints -inf END IF
An exception flag set to signaling remains signaling until set to quiet by either the IEEE_SET_FLAG or IEEE_SET_STATUS subroutines.
The compiler ensures that a call from scoping units using the IEEE_EXCEPTIONS or IEEE_ARITHMETIC intrinsic modules does not change the floating-point status other than by setting exception flags to signaling.
If a flag is set to signaling on entry into a scoping unit that uses the IEEE_EXCEPTIONS or IEEE_ARITHMETIC modules, the flag is set to quiet and then restored to signaling when leaving that scoping unit.
In a scoping unit that uses the IEEE_EXCEPTIONS or IEEE_ARITHMETIC modules, the rounding and halting modes do not change on entry. On return, the rounding and halting modes are the same as on entry.
Evaluating a specification expression can cause an exception to signal.
Exception handlers must not use the IEEE_EXCEPTIONS or IEEE_ARITHMETIC modules.
The following rules apply to format processing and intrinsic procedures:
In a sequence of statements that has no invocations of IEEE_GET_FLAG, IEEE_SET_FLAG, IEEE_GET_STATUS, IEEE_SET_HALTING, or IEEE_SET_STATUS, the following applies. If the execution of an operation would cause an exception to signal but after execution of the sequence no value of a variable depends on the operation, whether the exception is signaling depends on the optimization level. Optimization transformations may eliminate some code, and thus IEEE exception flags signaled by the eliminated code will not signal.
An exception will not signal if this could arise only during execution of an operation beyond those required or permitted by the standard.
For procedures defined by means other than Fortran, it is the responsibility of the user to preserve floating-point status.
XL Fortran does not always detect floating-point exception conditions for extended precision values. If you turn on floating-point exception trapping in programs that use extended precision, XL Fortran may also generate signals in cases where an exception does not really occur. See Detecting and trapping floating-point exceptions for more information.
Fortran 2003 IEEE derived types, constants, and operators are incompatible with the floating-point and inquiry procedures in xlf_fp_util, fpsets, and fpgets procedures. A value obtained from an IEEE procedure cannot be used in non-IEEE procedures. Within a single scoping unit, do not mix calls to the procedures in xlf_fp_util, fpsets, and fpgets with calls to the IEEE procedures. These procedures may change the floating-point status when called from scoping units that use the IEEE_EXCEPTIONS or IEEE_ARITHMETIC modules.
Example 1: In the following example, the main program calls procedure P which uses the IEEE_ARITHMETIC module. The procedure changes the floating-point status before returning. The example displays the changes to the floating-point status before calling procedure P, on entry into the procedure, on exit from P, and after returning from the procedure.
PROGRAM MAIN USE, INTRINSIC :: IEEE_ARITHMETIC INTERFACE SUBROUTINE P() USE IEEE_ARITHMETIC END SUBROUTINE P END INTERFACE LOGICAL, DIMENSION(5) :: FLAG_VALUES TYPE(IEEE_ROUND_TYPE) :: ROUND_VALUE CALL IEEE_SET_FLAG(IEEE_OVERFLOW, .TRUE.) CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, "MAIN: FLAGS ",FLAG_VALUES CALL P() CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, "MAIN: FLAGS ",FLAG_VALUES CALL IEEE_GET_ROUNDING_MODE(ROUND_VALUE) IF (ROUND_VALUE == IEEE_NEAREST) THEN PRINT *, "MAIN: ROUNDING MODE: IEEE_NEAREST" ENDIF END PROGRAM MAIN SUBROUTINE P() USE IEEE_ARITHMETIC LOGICAL, DIMENSION(5) :: FLAG_VALUES TYPE(IEEE_ROUND_TYPE) :: ROUND_VALUE CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, " P: FLAGS ON ENTRY: ",FLAG_VALUES CALL IEEE_SET_ROUNDING_MODE(IEEE_TO_ZERO) CALL IEEE_SET_FLAG(IEEE_UNDERFLOW, .TRUE.) CALL IEEE_GET_ROUNDING_MODE(ROUND_VALUE) IF (ROUND_VALUE == IEEE_TO_ZERO) THEN PRINT *, " P: ROUNDING MODE ON EXIT: IEEE_TO_ZERO" ENDIF CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, " P: FLAGS ON EXIT: ",FLAG_VALUES END SUBROUTINE P
When using the -qstrictieeemod compiler option to ensure compliance with rules for IEEE arithmetic, exception flags set before calling P are cleared on entry to P. Changes to the floating-point status occurring in P are undone when P returns, with the exception that flags set in P remain set after P returns:
MAIN: FLAGS T F F F F P: FLAGS ON ENTRY: F F F F F P: ROUNDING MODE ON EXIT: IEEE_TO_ZERO P: FLAGS ON EXIT: F F F T F MAIN: FLAGS T F F T F MAIN: ROUNDING MODE: IEEE_NEAREST
When the -qnostrictieeemod compiler option is in effect, exception flags which were set before calling P remain set on entry to P. Changes to the floating point status occurring in P are propagated to the caller.
MAIN: FLAGS T F F F F P: FLAGS ON ENTRY: T F F F F P: ROUNDING MODE ON EXIT: IEEE_TO_ZERO P: FLAGS ON EXIT: T F F T F MAIN: FLAGS T F F T F
Example 2: In the following example, the main program calls procedure Q which uses neither IEEE_ARITHMETIC nor IEEE_EXCEPTIONS. Procedure Q changes the floating-point status before returning. The example displays the changes to the floating-point status before calling Q, on entry into the procedure, on exit from Q, and after returning from the procedure.
PROGRAM MAIN USE, INTRINSIC :: IEEE_ARITHMETIC LOGICAL, DIMENSION(5) :: FLAG_VALUES TYPE(IEEE_ROUND_TYPE) :: ROUND_VALUE CALL IEEE_SET_FLAG(IEEE_OVERFLOW, .TRUE.) CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, "MAIN: FLAGS ",FLAG_VALUES CALL Q() CALL IEEE_GET_FLAG(IEEE_ALL, FLAG_VALUES) PRINT *, "MAIN: FLAGS ",FLAG_VALUES CALL IEEE_GET_ROUNDING_MODE(ROUND_VALUE) IF (ROUND_VALUE == IEEE_NEAREST) THEN PRINT *, "MAIN: ROUNDING MODE: IEEE_NEAREST" ENDIF END PROGRAM MAIN SUBROUTINE Q() USE XLF_FP_UTIL INTERFACE FUNCTION GET_FLAGS() LOGICAL, DIMENSION(5) :: GET_FLAGS END FUNCTION END INTERFACE LOGICAL, DIMENSION(5) :: FLAG_VALUES INTEGER(FP_MODE_KIND) :: OLDMODE FLAG_VALUES = GET_FLAGS() PRINT *, " Q: FLAGS ON ENTRY: ", FLAG_VALUES CALL CLR_FPSCR_FLAGS(FP_OVERFLOW) OLDMODE = SET_ROUND_MODE(FP_RND_RZ) CALL SET_FPSCR_FLAGS(TRP_OVERFLOW) CALL SET_FPSCR_FLAGS(FP_UNDERFLOW) IF (GET_ROUND_MODE() == FP_RND_RZ) THEN PRINT *, " Q: ROUNDING MODE ON EXIT: TO_ZERO" ENDIF FLAG_VALUES = GET_FLAGS() PRINT *, " Q: FLAGS ON EXIT: ", FLAG_VALUES END SUBROUTINE Q ! PRINT THE STATUS OF ALL EXCEPTION FLAGS FUNCTION GET_FLAGS() USE XLF_FP_UTIL LOGICAL, DIMENSION(5) :: GET_FLAGS INTEGER(FPSCR_KIND), DIMENSION(5) :: FLAGS INTEGER I FLAGS = (/ FP_OVERFLOW, FP_DIV_BY_ZERO, FP_INVALID, & & FP_UNDERFLOW, FP_INEXACT /) DO I=1,5 GET_FLAGS(I) = (GET_FPSCR_FLAGS(FLAGS(I)) /= 0) END DO END FUNCTION
When using the -qstrictieeemod compiler option to ensure compliance with rules for IEEE arithmetic, exception flags set before Q remain set on entry into Q. Changes to the floating-point status occurring in Q are undone when Q returns, with the exception that flags set in Q remain set after Q returns:
MAIN: FLAGS T F F F F Q: FLAGS ON ENTRY: T F F F F Q: ROUNDING MODE ON EXIT: TO_ZERO Q: FLAGS ON EXIT: F F F T F MAIN: FLAGS T F F T F MAIN: ROUNDING MODE: IEEE_NEAREST
When the -qnostrictieeemod option is in effect, exception flags set before calling Q remain set on entry into Q. Changes to the floating point status occurring in Q are propagated to the caller.
MAIN: FLAGS T F F F F Q: FLAGS ON ENTRY: T F F F F Q: ROUNDING MODE ON EXIT: TO_ZERO Q: FLAGS ON EXIT: F F F T F MAIN: FLAGS F F F T F