Fortran 2003 Standard

IEEE Modules and support

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.

Notes:
  1. XL Fortran Extended Precision floating-point numbers are not in the format suggested by the IEEE standard. As a result, some parts of the modules do not support REAL(16).
  2. IEEE modules generate SIGFPE signals on Linux.

Compiling and exception handling

XL Fortran provides a number of options for strict compliance with the IEEE standard.

Related information

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.

General rules for implementing IEEE modules

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.

IEEE Derived data types and constants

The IEEE modules define the following derived types.

IEEE_FLAG_TYPE

Type

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:

IEEE_OVERFLOW
Occurs when the result for an intrinsic real operation or an assignment has an exponent too large to be represented. This exception also occurs when the real or imaginary part of the result for an intrinsic complex operation or assignment has an exponent too large to be represented.

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.

IEEE_DIVIDE_BY_ZERO
Occurs when a real or complex division has a nonzero numerator and a zero denominator.
IEEE_INVALID
Occurs when a real or complex operation or assignment is invalid.
IEEE_UNDERFLOW
Occurs when the result for an intrinsic real operation or assignment has an absolute value too small to be represented by anything other than zero, and loss of accuracy is detected. The exception also occurs when the real or imaginary part of the result for an intrinsic complex operation or assignment has an absolute value that is too small to be represented by anything other than zero, and loss of accuracy is detected.

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.

IEEE_INEXACT
Occurs when the result of a real or complex assignment or operation is not exact.

The following constants are arrays of IEEE_FLAG_TYPE:

IEEE_USUAL
An array named constant containing IEEE_OVERFLOW, IEEE_DIVIDE_BY_ZERO, and IEEE_INVALID elements in order.
IEEE_ALL
An array named constant containing IEEE_USUAL, IEEE_UNDERFLOW, and IEEE_INEXACT elements in order.

IEEE_STATUS_TYPE

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.

IEEE_CLASS_TYPE

Type

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

IEEE_ROUND_TYPE

Type

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:

IEEE_NEAREST
Rounds the exact result to the nearest representable value.
IEEE_TO_ZERO
Rounds the exact result to the next representable value, towards zero.
IEEE_UP
Rounds the exact result to the next representable value, towards positive infinity.
IEEE_DOWN
Rounds the exact result to the next representable value, towards negative infinity.
IEEE_OTHER
Indicates that the rounding mode does not conform to the IEEE standard.

IEEE_FEATURES_TYPE

Type

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

IEEE Operators

The IEEE_ARITHMETIC module defines two sets of elemental operators for comparing variables of IEEE_CLASS_TYPE or IEEE_ROUND_TYPE.

==
Allows you to compare two IEEE_CLASS_TYPE or two IEEE_ROUND_TYPE values. The operator returns true if the values are identical or false if they differ.
/=
Allows you to compare two IEEE_CLASS_TYPE or two IEEE_ROUND_TYPE values. The operator returns true if the values differ or false if they are identical.

IEEE PROCEDURES

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.

Rules for Using IEEE Procedures

Type

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.

IEEE_CLASS(X)

Type

An elemental IEEE class function. Returns the IEEE class of a floating-point value.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

The result is of type IEEE_CLASS_TYPE.

Rules

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.

Examples

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

IEEE_COPY_SIGN(X, Y)

Type

An elemental IEEE copy sign function. Returns the value of X with the sign of Y.

Module

IEEE_ARITHMETIC

Syntax

Where X and Y are of type real, though they may be of different kinds.

Result type and attributes

The result is of the same kind and type as X.

Rules

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.

Note:
XL Fortran REAL(16) numbers have no signed zero.

Examples

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

IEEE_GET_FLAG(FLAG, FLAG_VALUE)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

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.

Examples

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

IEEE_GET_HALTING_MODE(FLAG, HALTING)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where FLAG is an INTENT(IN) argument of type IEEE_FLAG_TYPE specifying the IEEE flag. HALTING is an INTENT(OUT) default logical.

Examples

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

IEEE_GET_ROUNDING_MODE (ROUND_VALUE)

Type

An IEEE subroutine. Sets ROUND_VALUE to the current IEEE rounding mode.

Module

IEEE_ARITHMETIC

Syntax

Where ROUND_VALUE is an INTENT(OUT) scalar of type IEEE_ROUND_TYPE.

Examples

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

IEEE_GET_STATUS(STATUS_VALUE)

Type

An IEEE subroutine. Retrieves the current IEEE floating-point status.

Module

IEEE_ARITHMETIC

Syntax

Where STATUS_VALUE is an INTENT(OUT) scalar of type IEEE_STATUS_TYPE.

Rules

You can only use STATUS_VALUE in an IEEE_SET_STATUS invocation.

Examples

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

IEEE_IS_FINITE(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is of type default logical.

Rules

To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.

Examples

USE, INTRINSIC :: IEEE_ARITHMETIC
REAL :: X = 1.0
IF (IEEE_SUPPORT_DATATYPE(X)) THEN
  PRINT *, IEEE_IS_FINITE(X)    ! Prints true
ENDIF

IEEE_IS_NAN(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is of type default logical.

Rules

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.

Examples

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

IEEE_IS_NEGATIVE(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is of type default logical.

Rules

To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.

Examples

USE, INTRINSIC :: IEEE_ARITHMETIC
IF (IEEE_SUPPORT_DATATYPE(1.0)) THEN
  PRINT *, IEEE_IS_NEGATIVE(1.0)    ! Prints false
ENDIF

IEEE_IS_NORMAL(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is of type default logical.

Rules

To ensure compliance with the Fortran 2003 standard, the IEEE_SUPPORT_DATATYPE(X) must return with a value of true.

Examples

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

IEEE_LOGB(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is the same type and kind as X.

Rules

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.

Examples

USE, INTRINSIC :: IEEE_ARITHMETIC
IF (IEEE_SUPPORT_DATATYPE(1.1)) THEN
  PRINT *, IEEE_LOGB(1.1)  ! Prints 0.0
ENDIF

IEEE_NEXT_AFTER(X, Y)

Type

An elemental IEEE function. Returns the next machine-representable neighbor of X in the direction towards Y.

Module

IEEE_ARITHMETIC

Syntax

Where X and Y are of type real.

Result type and attributes

Where the result is the same type and kind as X.

Rules

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.

Examples

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

IEEE_REM(X, Y)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X and Y are of type real.

Result type and attributes

Where the result is of type real with the same kind as the argument with greater precision.

Rules

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.

Examples

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

IEEE_RINT(X)

Type

An elemental IEEE function. Rounds to an integer value according to the current rounding mode.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real.

Result type and attributes

Where the result is the same type and kind as X.

Rules

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.

Examples

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

IEEE_SCALB(X, I)

Type

An elemental IEEE function. Returns X * 2I.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real and I is of type INTEGER.

Result type and attributes

Where the result is the same type and kind as X.

Rules

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.

Examples

USE, INTRINSIC :: IEEE_ARITHMETIC
IF (IEEE_SUPPORT_DATATYPE(1.0)) THEN
  PRINT *, IEEE_SCALB(1.0,2)       ! Prints 4.0
ENDIF

IEEE_SELECTED_REAL_KIND([P, R])

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where P and R are both scalar optional arguments of type integer.

Rules

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.

Examples

       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 

IEEE_SET_FLAG(FLAG, FLAG_VALUE)

Type

An IEEE subroutine. Assigns a value to an IEEE exception flag.

Module

IEEE_EXCEPTIONS

Syntax

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.

Rules

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.

Examples

USE, INTRINSIC :: IEEE_EXCEPTIONS
CALL IEEE_SET_FLAG(IEEE_OVERFLOW, .TRUE.)
! IEEE_OVERFLOW is now signaling

IEEE_SET_HALTING_MODE(FLAG, HALTING)

Type

An IEEE subroutine. Controls continuation or halting after an exception.

Module

IEEE_EXCEPTIONS

Syntax

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.

Rules

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.

Examples

@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

IEEE_SET_ROUNDING_MODE (ROUND_VALUE)

Type

An IEEE subroutine. Sets the current rounding mode.

Module

IEEE_ARITHMETIC

Syntax

Where ROUND_VALUE is an INTENT(IN) argument of type IEEE_ROUND_TYPE specifying the rounding mode.

Rules

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.

Examples

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

IEEE_SET_STATUS(STATUS_VALUE)

Type

An IEEE subroutine. Restores the value of the floating-point status.

Module

IEEE_ARITHMETIC

Syntax

Where STATUS_VALUE is an INTENT(IN) argument of type IEEE_STATUS_TYPE specifying the floating-point status.

Rules

STATUS_VALUE must have been set previously by IEEE_GET_STATUS.

IEEE_SUPPORT_DATATYPE or IEEE_SUPPORT_DATATYPE(X)

Type

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.

Note:
NaN and Infinity are not fully supported for REAL(16). Arithmetic operations do not necessarily propagate these values.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

Examples

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

IEEE_SUPPORT_DENORMAL or IEEE_SUPPORT_DENORMAL(X)

Type

An inquiry IEEE function. Determines whether the current implementation supports denormalized numbers.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_DIVIDE or IEEE_SUPPORT_DIVIDE(X)

Type

An inquiry IEEE function. Determines whether the current implementation supports division to the accuracy of the IEEE standard.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_FLAG(FLAG) or IEEE_SUPPORT_FLAG(FLAG, X)

Type

An inquiry IEEE function. Determines whether the current implementation supports an exception.

Module

IEEE_EXCEPTIONS

Syntax

Where FLAG is a scalar argument of IEEE_FLAG_TYPE. X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_HALTING(FLAG)

Type

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).

Module

IEEE_EXCEPTIONS

Syntax

Where FLAG is an INTENT(IN) argument of IEEE_FLAG_TYPE.

Result type and attributes

The result is a scalar of type default logical.

Rules

The result returns with a value of true for all flags.

IEEE_SUPPORT_INF or IEEE_SUPPORT_INF(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_IO or IEEE_SUPPORT_IO(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_NAN or IEEE_SUPPORT_NAN(X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_ROUNDING (ROUND_VALUE) or IEEE_SUPPORT_ROUNDING (ROUND_VALUE, X)

Type

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.

Module

IEEE_ARITHMETIC

Syntax

Where ROUND_VALUE is a scalar argument of IEEE_ROUND_TYPE. X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_SQRT or IEEE_SUPPORT_SQRT(X)

Type

An inquiry IEEE function. Determines whether the current implementation supports the SQRT as defined by the IEEE standard.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_SUPPORT_STANDARD or IEEE_SUPPORT_STANDARD(X)

Type

An inquiry IEEE function. Determines whether all facilities defined in the Fortran 2003 standard are supported.

Module

IEEE_ARITHMETIC

Syntax

Where X is a scalar or array valued argument of type real.

Result type and attributes

The result is a scalar of type default logical.

Rules

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.

IEEE_UNORDERED(X, Y)

Type

An elemental IEEE unordered function.

Module

IEEE_ARITHMETIC

Syntax

Where X and Y are of type real.

Result type and attributes

The result is of type default logical.

Rules

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.

Examples

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

IEEE_VALUE(X, CLASS)

Type

An elemental IEEE function. Generates an IEEE value as specified by CLASS.

Note:
Implementation of this function is platform and compiler dependent due to variances in NaN processing on differing platforms. A NaN value saved in a binary file that is read on a different platform than the one that generated the value will have unspecified results.

Module

IEEE_ARITHMETIC

Syntax

Where X is of type real. CLASS is of type IEEE_CLASS_TYPE.

Result type and attributes

The result is of the same type and kind as X.

Rules

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.

Examples

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

Rules for floating-point status

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.

Examples

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
End of Fortran 2003 Standard