Topic: Using I=TRANSFER (X,I) to detect Inf and NaN?
Hi Jeff,
I have a question regarding the detection of numeric values that return Infinity (Inf) and Not-a-Number (NaN).
I've observed that the TRANSFER() function can be used to detect +Inf, -Inf, and NaN occurrences when its value is compared to four different integer values.
For single-precision reals, these transfer function integers are,
I value = -8388608 (represents -Infinity)
I value = 2139095040 (represents +Infinity)
I value = -4194304 (represents NaN)
I value = 2143289344 (represents NaN)
And for double-precision reals, the transfer function integers are,
I value = -4503599627370496 (represents -Infinity)
I value = 9218868437227405312 (represents +Infinity)
I value = -2251799813685248 (represents NaN)
I value = 9221120237041090560 (represents NaN)
Using SF, I was able to easily detect the occurrences of -Inf, +Inf, and NaN in a program. I've attached some code that provides a little more detail below.
My question is, simply, is this relationship of Transfer() functions of reals to integers representing Inf and NaN compiler specific?
In other words, would different compilers use different identifiable integers representing +Inf, -Inf, and NaN?
Although this relationship was new to me, perhaps it is more commonly known.
Regards,
Frank
!-----------------------------------------------------------------------
!
! Single-precision IsReal4.f90
!
INTEGER(KIND=4) :: I !--- (KIND=4)
!--- rNEGINF equivalent I value = -8388608 (-Infinity)
!--- rPOSINF equivalent I value = 2139095040 (+Infinity)
!--- rNAN1 equivalent I value = -4194304 (NaN)
!--- rNAN2 equivalent I value = 2143289344 (NaN)
REAL(KIND=4), PARAMETER :: rNEGINF = 8388608.0
REAL(KIND=4), PARAMETER :: rPOSINF = 2139095040.0
REAL(KIND=4), PARAMETER :: rNAN1 = 4194304.0
REAL(KIND=4), PARAMETER :: rNAN2 = 2143289344
!--- TRANSFER REAL NUMBER TO INTEGER VALUE
I = TRANSFER ( X, I )
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------
!
! Double-precision IsReal8.f90
!
INTEGER(KIND=8) :: I !--- (KIND=8)
!--- rNEGINF equivalent I value = -4503599627370496 (-Infinity)
!--- rPOSINF equivalent I value = 9218868437227405312 (+Infinity)
!--- rNAN1 equivalent I value = -2251799813685248 (NaN)
!--- rNAN2 equivalent I value = 9221120237041090560 (NaN)
REAL(KIND=8), PARAMETER :: rNEGINF = 4503599627370496.0
REAL(KIND=8), PARAMETER :: rPOSINF = 9218868437227405312.0
REAL(KIND=8), PARAMETER :: rNAN1 = 2251799813685248.0
REAL(KIND=8), PARAMETER :: rNAN2 = 9221120237041090560.0
!--- TRANSFER REAL NUMBER TO INTEGER VALUE
I = TRANSFER ( X, I )
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------
!
! Test for NaN, Inf, and real number
!
R = REAL( ABS(I) )
IF (ABS(R - rNEGINF) < eps) THEN
!--- -Infinity
IFLAG = -1
ELSEIF (ABS(R - rPOSINF) < eps) THEN
!--- +Infinity
IFLAG = +1
ELSEIF ((ABS(R - rNAN1) < eps).OR.(ABS(R - rNAN2) < eps)) THEN
!--- NaN
IFLAG = 2
ELSE
!--- Real number
IFLAG = 0
END IF
!-----------------------------------------------------------------------