The parameter file /opt/intel/fc/9.0/include/fordef.for contains symbols and INTEGER*4 values corresponding to the classes of floating-point representations. Some of these classes are exceptional ones such as bit patterns that represent positive denormalized numbers.
With this file of symbols and with the FP_CLASS intrinsic function, you have the flexibility of identifying exceptional numbers so that, for example, you can replace positive and negative denormalized numbers with true zero.
The following is a simple example of identifying floating-point bit representations:
include 'fordef.for'
real*4 a
integer*4 class_of_bits
a = 57.0 !
Bit pattern is a finite number
class_of_bits = fp_class(a)
if ( class_of_bits .eq. for_k_fp_pos_norm .or.
&
class_of_bits .eq. for_k_fp_neg_norm )
then
print *, a, ' is a non-zero and non-exceptional value'
else
print *, a, ' is zero or an exceptional value'
end if
end
In this example, the symbol for_k_fp_pos_norm in the file /opt/intel/fc/9.0/include/fordef.for plus the REAL*4 value 57.0 to the FP_CLASS intrinsic function results in the execution of the first print statement.
The table below explains the symbols in the file /opt/intel/fc/9.0/include/fordef.for and their corresponding floating-point representations.
Symbols in File fordef.for
Symbol Name |
Class of Floating-Point Bit Representation |
FOR_K_FP_SNAN |
Signaling NaN |
FOR_K_FP_QNAN |
Quiet NaN |
FOR_K_FP_POS_INF |
Positive infinity |
FOR_K_FP_NEG_INF |
Negative infinity |
FOR_K_FP_POS_NORM |
Positive normalized finite number |
FOR_K_FP_NEG_NORM |
Negative normalized finite number |
FOR_K_FP_POS_DENORM |
Positive denormalized number |
FOR_K_FP_NEG_DENORM |
Negative denormalized number |
FOR_K_FP_POS_ZERO |
Positive zero |
FOR_K_FP_NEG_ZERO |
Negative zero |
Another example of using file fordef.for and intrinsic function FP_CLASS follows. The goals of this program are to quickly read any 32-bit pattern into a REAL*4 number from an unformatted file with no exception reporting and to replace denormalized numbers with true zero:
include 'fordef.for'
real*4
a(100)
integer*4
class_of_bits
! open
an unformatted file as unit 1
! ...
read (1)
a
do i =
1, 100
class_of_bits
= fp_class(a(i))
if
( class_of_bits .eq. for_k_fp_pos_denorm .or.
&
class_of_bits
.eq. for_k_fp_neg_denorm )
then
a(i)
= 0.0
end
if
end do
close (1)
end
You can compile this program with any value of -fpen. Intrinsic function FP_CLASS helps to find and replace denormalized numbers with zeroes before the program can attempt to perform calculations on the denormalized numbers. On the other hand, if this program did not replace denormalized numbers read from unit 1 with zeroes and the program was compiled with -fpe0, then the first attempted calculation on a denormalized number would result in a floating-point exception.
File fordef.for and intrinsic function FP_CLASS can work together to identify NaNs. A variation of the previous example would contain the symbols for_k_fp_snan and for_k_fp_qnan in the IF statement. A faster way to do this is based on the intrinsic function ISNAN. One modification of the previous example, using ISNAN, follows:
! The ISNAN function does not need file fordef.for
real*4 a(100)
! open an unformatted file as unit 1
! ...
read (1) a
do i = 1, 100
if ( isnan (a(i)) ) then
print *, 'Element ', i, ' contains a NaN'
end if
end do
close (1)
end