Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

NaN

YertleTheTurtle
Beginner
632 Views

In a previous post on another thread, Steve Lionel wrote, in reference to a Real(Kind=8) variable:

"non-REAL values have no corresponding NaN that can be used"

That would be true for a double precision number on a 32 bit machine.

On a 64 bit machine is that statement still true?

Thank you.

0 Kudos
7 Replies
IanH
Honored Contributor II
632 Views
DOUBLE PRECISION is just a synonym for a kind of real that has more precision that default real - double precision variables are still reals. The way values of real type are stored in memory using ifort (anything on x86 really) reserves some bit patterns to represent things like NaN's, INF, etc. Steve was probably referring to integer and character variables. With those types on ifort, all possible bit patterns map across to valid values. Platform bitness doesn't come into this.
0 Kudos
YertleTheTurtle
Beginner
632 Views
No, he was specifically referring to a statement like: real(kind=8):: X His argument was that since "X" wasn't "Real", in the sense that it fills two 32 bit words, there is no NaN in existence that could be used to trap an uninitialized value. So, I wondered if that would be true on a 64 bit machine where Kind=8 fills one word.
0 Kudos
IanH
Honored Contributor II
632 Views
The representation for real(8) on a x86 family processor in 32 bit or 64 bit mode is the same (it is the IEEE double precision format). real(4) is the same across the two as well (it uses the IEEE single precision format). Both these formats have provision to represent NaN's and other "not-normal" numbers. I've used the Intel 64 and IA-32 Architectures Software Developer's manuals when I've previously wanted details on the representations (or perhaps when I was having difficulty sleeping), but there are probably more concise and direct references out there. F2003 introduced language support for the IEEE floating point formats via some intrinsic modules. You can use the IEEE_VALUE procedure from the IEEE_ARITHMETIC intrinsic module on ifort to generate a NaN value for the real(4) or real(8) representation. You can use the IEEE_IS_NAN function from that same module to test for a NaN value. This is a reasonably portable approach across current Fortran processors that run on hardware that support those formats (gfortran is one notable exception, but it is easy enough to hack the basic bits of IEEE_ARITHMETIC together, I think I started with something that TimP had written).
0 Kudos
mecej4
Honored Contributor III
632 Views
His argument was that since "X" wasn't "Real", in the sense that it fills two 32 bit words, there is no NaN in existence that could be used to trap an uninitialized value. So, I wondered if that would be true on a 64 bit machine where Kind=8 fills one word.
That is a misinterpretation of what Steve said. Ever since the advent of the 8087 (circa 1978), which was a coprocessor for the 8/16 bit 8088, real numbers of 32, 64 and 80 bit have been supported on Intel/AMD/Cyrix/... CPUs, whether in an integrated FPU or a separate coprocessor. As IanH has pointed out, you are confusing integer types and floating point types.
0 Kudos
jimdempseyatthecove
Honored Contributor III
632 Views
From IEE-754: The exponents 0x000 and 0x7ff have a special meaning: 0x000 is used to represent zero (if mantissa=0) and subnormals (if mantissa≠0); and 0x7FF is used to represent ∞ (if mantissa fraction=0) and NaNs (if mantissa fraction≠0). All bit patterns are valid encoding. Therefore you have 2^52-1 different NaN's half of which are Signaling (SNaN) the other half are Quite (QNaN). The Signaling form could potentially be used to trap uninitialized variables... Provided the action (read, read modify write) is by use of floating point (FPU, float SSE/AVX, double SSE/AVX). If used by integer operation (e.g. mov rax,[locOfSaN]) then no trap would occur. Also note when two variables are an NaN (one of any of the 2^52-1), they are never == when using floating point instructions, but may be == when using integer compare for equality (1 in 2^52-1 for random distribution of NaN). Meaning: rely on IF(ISNAN(X)) CALL OOPS() Jim Dempsey
0 Kudos
TimP
Honored Contributor III
632 Views
According to Fortran standard, the legacy isnan() ought to be replaced by ieee_is_nan() (USE ieee_arithmetic). Among the reasons for using isnan is that default optimizations in ifort don't allow for relational expressions to respect possibility of NaN. I don't see a clean way to use integer compare to see whether data have been polluted by real data including NaN.
0 Kudos
Steven_L_Intel1
Employee
632 Views
mecej4 and the others are correct. When I said "REAL" I meant the datatype, not a specific KIND (single, double, etc.). I think the problem with presetting REAL values to a NaN, at least, is that there is no simple bit pattern I know of that suffices for all three kinds of REAL. That means a complicated and slow initialization of each value individually. Things were much simpler before IEEE FP.... And indeed, there is no concept of a NaN for Integer, character, logical or derived type.
0 Kudos
Reply