Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Best way to get a NaN

1,325 views
Skip to first unread message

Dominik Gronkiewicz

unread,
Jun 9, 2018, 4:06:13 PM6/9/18
to
In numpy, when I want to assign NaN to one element of the array (to mask it, for example), I can do:

a[4] = np.nan

I believe that no such constant exists in Fortran, and hacks like 1/0 had to be used. Here (https://stackoverflow.com/questions/31971836/having-parameter-constant-variable-with-nan-value-in-fortran) I have found a following solution involving IEEE_ARITHMETIC module:

use, intrinsic :: iso_fortran_env
use, intrinsic :: ieee_arithmetic
integer(int32) i
real(real32) x

x = ieee_value(x, ieee_quiet_nan)
i = transfer(x,i)

But they also commented:

"Note that ieee_value() can't be used directly in initialization: a reference to it isn't a constant expression. For such use, take this approach to get the bit pattern and apply the method of the other answer."

I guess all methods work, but what is the best and most portable solution (I target x86_64, i386 and Raspberry Pi / ARM)? Also, why there is a need to store the bit pattern in an integer?

pmk

unread,
Jun 10, 2018, 10:20:22 AM6/10/18
to
1.0/0 is ∞, not a NaN. Try 0.0 * ∞.

Dominik Gronkiewicz

unread,
Jun 11, 2018, 7:38:17 AM6/11/18
to
W dniu niedziela, 10 czerwca 2018 16:20:22 UTC+2 użytkownik pmk napisał:
> 1.0/0 is ∞, not a NaN. Try 0.0 * ∞.

Either way, I'd rather use some more elegant solution, hence my question :)

michael siehl

unread,
Jun 11, 2018, 7:53:37 AM6/11/18
to
Just to point to some other option:

In the past (in the 1990s), I did use IMSL routine AMACH(6) to receive a value for NaN. For some backround information see the section 'Machine-Dependent Constants' in the chapter 'Reference Material' here: http://www.math.yorku.ca/Who/Faculty/Stauffer/IMSL-manuals/MATH.pdf

I think the problem with NaN was that not all computers did offer support for representing or signaling such values.

(I believe to remember that, back in the 1990s, it was required for Fortran mixed-language programming on Microsoft Windows with Visual Basic 5, which did not support NaN at all. That may have changed with Visual Basic 6).

nshaffer

unread,
Jun 16, 2018, 6:04:48 PM6/16/18
to
I'm also confused about the need to transfer the bit pattern to an equal-sized integer. 'missing = ieee_value(missing, ieee_quiet_nan)' seems sufficient for assigning NaN to a variable. The only reason I can think of to also store the bit pattern is to be able to test if a value is NaN by comparing bit patterns. But if you have ieee_arithmetic, you have ieee_is_nan, so it's pointless.

The approach suggested on the Fortran Rosetta Code entry on Undefined Values is to use an internal read to create a NaN value:

program nantest
implicit none

real :: nan
character(len=3) :: nanstr = 'nan'

read(nanstr, *) nan

print *, nan ! 'NaN'
print *, nan == nan ! 'F'

end program nantest

This seems like a gross but maybe viable alternative if you're stuck with a compiler that doesn't support ieee_arithmetic. Whether this is more or less palatable than transfer'ing a magic integer I think is a matter of taste. The latter has a magic number, the former involves crossing your fingers that reading 'nan' actually maps to a NaN value. Not sure if the standard has anything to say on this.

One "gotcha" that might come up with these home-spun NaN values is that many distinct bit patterns map to NaN values. If you compare the bit pattern of a real variable to that of your home-spun NaN value, you are making a much narrower comparison than what is done by ieee_is_nan. On the other hand, this is a good thing if your intent is just to your NaN as a masking value. If an array contains a NaN that doesn't match your masking value's bit pattern, then that could be a hint that something went wrong.

Ian Harvey

unread,
Jun 16, 2018, 6:17:50 PM6/16/18
to
Read the "also commented bit" above. The stackoverflow question being
linked to wanted the NaN as a constant. The approach taken in the
linked answer was to separately (different program running on the same
Fortran processor) determine a bit pattern that defined a NaN, and then
use that bit pattern to define the constant in the other Fortran program
that required it.

If you don't need the NaN in a constant expression, then you can (and
should) just use ieee_value. If your processor doesn't support
ieee_value, then you will need to use some other less portable hack.
However, one of the reasons that a processor might not support
ieee_value is that the processor simply does not support the concept of
a NaN for the kind of real of interest, no hack is going to work around
that.

michael siehl

unread,
Jun 17, 2018, 6:47:33 AM6/17/18
to
|I'm also confused about the need to transfer the bit pattern to an equal-sized |integer. 'missing = ieee_value(missing, ieee_quiet_nan)' seems sufficient for |assigning NaN to a variable. The only reason I can think of to also store the |bit |pattern is to be able to test if a value is NaN by comparing bit patterns. |But if |you have ieee_arithmetic, you have ieee_is_nan, so it's pointless.

I can only point to the IMSL manual, page 1204, http://www.math.yorku.ca/Who/Faculty/Stauffer/IMSL-manuals/MATH.pdf :

"...
The functions IFNAN and DIFNAN are provided to facilitate the transfer of
programs across computer systems. This is because the check for NaN can be
tricky and not portable across computer systems that do not adhere to the IEEE
standard.
For example, on computers that support the IEEE standard for binary
arithmetic (see IEEE 1985), NaN is specified as a bit format not equal to itself. Thus, the check is performed as
IFNAN = X .NE. X
On other computers that do not use IEEE floating-point format, the check can be
performed in single precision as
IFNAN = X .EQ. AMACH(6)

The function IFNAN or DIFNAN is equivalent to the specification of the function
Isnan listed in the Appendix, (IEEE 1985).
..."

jfh

unread,
Jun 17, 2018, 6:33:26 PM6/17/18
to
What I sometimes use is this little function:

elemental real function naninf(n) ! Returns -Inf,NaN,Inf if n <,=,> 0
integer,intent(in)::n
character(4):: cinf(3)
cinf = (/'NaN ','-Inf','+Inf'/)
read(cinf(merge(1,merge(2,3,n<0),n==0)),*) naninf
end function naninf

I don't use overflowing or invalid real arithmetic for that because some compilers would refuse to compile, some would crash at run-time, and some would run happily. Warning: there are usually at least two different NaNs of each real kind (for signalling and quiet NaNs), and what the above function gives may be neither of the IEEE ones. I found that 4 different compilers (gfortran, g95 and ifort on x86_64 and Solaris f95 on a Sun) gave 4 different integer values of transfer(naninf(0),1) but each treated all 4 as NaN when they were transferred back to real.

Lisa Lowe

unread,
Jun 30, 2018, 8:23:08 AM6/30/18
to
If x.ne.x, then NaN

Lisa Lowe

unread,
Jun 30, 2018, 8:25:31 AM6/30/18
to
Sorry, I think the question is “how do I assign NaN”. Zero over zero is NaN, integer not float (0/0)

Lisa Lowe

unread,
Jun 30, 2018, 8:39:01 AM6/30/18
to
My gosh, sorry for triple posting!

I looked at one of my codes...the problem is the smarter the compiler is, the harder it was to do this- and if you have debugging on, it will almost always fail.

So what I did (doesn’t work on [I forget which compiler and which settings...])

I use it to initialize arrays to NaN (or whatever) (a fill value function)

Real X, Fillval
X=-1
Fillval = sqrt(x)

If you just do Fillval= sqrt(-1) without using x, most any compiler which give an error right away.

Michael Siehl

unread,
Jun 30, 2018, 11:35:19 AM6/30/18
to
As far as I do understand:

The check IFNAN = X .NE. X (comparing the bit format with itself) is done internally by IMSL routine IFNAN (or the IEEE ISNAN function), on computers that support the IEEE standard for binary arithmetic. Anything else (e.g. on computers that do not support that IEEE standard) may not be portable.

Persoanlly, I do not use NaN values for any initializations. Further, I am not sure if a bit format that is not equal to itself can be copied or used for anything else than identifying NaN.

Cheers

jfh

unread,
Jul 1, 2018, 10:17:46 PM7/1/18
to
If by "bit format" you mean the sequence of bits stored as a NaN then it can be equal to itself. It becomes not equal to itself when the compiler has to treat it as a real number. The proof is in this program and the output from gfortran and ifort below it.

program testnaninf3
implicit none
integer i
i = transfer(naninf(0),1)
print '(A,B32.32)','NaN transferred to integer with bits ',i
print *,'i==i ?',i==i,'NaN==NaN ?',naninf(0)==naninf(0)
contains
elemental real function naninf(n) ! Returns -Inf,NaN,Inf if n <,=,> 0
integer,intent(in)::n
character(4):: cinf(3)
cinf = ['NaN ','-Inf','+Inf']
read(cinf(merge(1,merge(2,3,n<0),n==0)),*) naninf
end function naninf
end program testnaninf3

Gfortran output on an x86_64 system:

NaN transferred to integer with bits 01111111110000000000000000000000
i==i ? T NaN==NaN ? F

Ifort output on an x86_64 system:

NaN transferred to integer with bits 11111111110000000000000000000000
i==i ? T NaN==NaN ? F

Michael Siehl

unread,
Jul 2, 2018, 10:13:21 AM7/2/18
to

I have strong doubts that such results, or checking for NaN's in general, is reliable portable.

Thus, my personal simple view: NaN is the result of an invalid calculation (or operation) but not the result of an assignment. NaN is Not a Number and as such not within the range of the intrinsic numeric data types, and thus, nothing I would use for intialization.

Lisa Lowe

unread,
Jul 3, 2018, 8:41:13 AM7/3/18
to
I agree that using NaNs on purpose is not a good idea for production code, but for scientific research-grade code there are several reasons why you would want to initialize to NaN - at least during testing. So with that in mind, I am also very interested in the OP’s question: has anyone has figured out how to do this in a way that is ideally portable and at minimum doesn’t make the compiler barf with debug on?

Wolfgang Kilian

unread,
Jul 3, 2018, 9:38:04 AM7/3/18
to
On 03.07.2018 14:41, Lisa Lowe wrote:
> I agree that using NaNs on purpose is not a good idea for production code, but for scientific research-grade code there are several reasons why you would want to initialize to NaN - at least during testing. So with that in mind, I am also very interested in the OP’s question: has anyone has figured out how to do this in a way that is ideally portable and at minimum doesn’t make the compiler barf with debug on?
>

I use the -nan compiler option of the NAG compiler. The option
initializes *all* real numbers with NaN, unless they are initialized
explicitly in the code. Very useful for debugging.

I don't think that this option breaks any rule of the standard, and it
certainly can't break standard-conforming code. If the option produces
a NaN anywhere at runtime, there is a bug in the code. Nevertheless
this is a compiler-specific extension, and cannot be qualified as portable.

-- Wolfgang

Lisa Lowe

unread,
Jul 3, 2018, 10:28:12 AM7/3/18
to
NAG is one of the compilers we don't use... :( We use intel, gnu, and sometimes test on pgi.

So according to the internets, for gnu it is -finit-real=nan, for intel is -init=snan.

Still maybe won't work as planned, but that will be worth a try...it seems that these compilers provide this flag to help weed out uninitialized variables (which other debug flags will do for you anyway), and not specifically for if you really want to initialize to a NaN.

An example for the folks who think we are bat-crazy for wanting to do that: you might want it as a tracer on input forcings and boundary condition effects, or for output to a file where you want the viz tool to see a 'missing' value. We do other things that get that job done, but using NaNs for that would be way cooler and expose unphysical behaviors faster then just setting BC's to a number that you think is stupid enough to break the code or at least have the decency to make your visualizations look bad.

Wolfgang Kilian

unread,
Jul 3, 2018, 11:14:05 AM7/3/18
to
On 03.07.2018 16:28, Lisa Lowe wrote:
> NAG is one of the compilers we don't use... :( We use intel, gnu, and sometimes test on pgi.
>
> So according to the internets, for gnu it is -finit-real=nan, for intel is -init=snan.

Yes, these should do the job as well.

> Still maybe won't work as planned, but that will be worth a try...it seems that these compilers provide this flag to help weed out uninitialized variables (which other debug flags will do for you anyway), and not specifically for if you really want to initialize to a NaN.

Other debug flags will likely slow down the code, while NaN
initialization should have no effect except maybe at startup - in
principle. Without guarantee, I think that it doesn't hurt for
production runs. And I'm not confident that other flags will detect
stuff like individual uninitialized array elements returned from
external subroutines, etc.

> An example for the folks who think we are bat-crazy for wanting to do that: you might want it as a tracer on input forcings and boundary condition effects, or for output to a file where you want the viz tool to see a 'missing' value. We do other things that get that job done, but using NaNs for that would be way cooler and expose unphysical behaviors faster then just setting BC's to a number that you think is stupid enough to break the code or at least have the decency to make your visualizations look bad.

Yes, the problem is that if you are treating NaN as a magic number,
you're treating it as a number of some kind, which it isn't. Using the
IEEE extensions might fix this properly, however, assuming that the
initialization option is actually IEEE compatible.

-- Wolfgang


Thomas Jahns

unread,
Jul 3, 2018, 12:04:48 PM7/3/18
to
On 07/03/18 16:28, Lisa Lowe wrote:
> An example for the folks who think we are bat-crazy for wanting to do that:

You are indeed about to do something which only leads to problems down the road,
making your "magic" tracer indistinguishable from floating point errors. If you
have intentional missing values the way to represent that is as a separate mask,
which can then be used to prevent unitialized values to enter any computation.
The only sane way to deal with NaNs is to stop the program, identify the reason
why they occur, fix the program and start again. A program that produces NaNs is
executing undefined behaviour which means the whole program is undefined from
the point of view of the language definition, i.e. it's not a Fortran program.

> you might want it as a tracer on input forcings and boundary condition
> effects, or for output to a file where you want the viz tool to see a
> 'missing' value. We do other things that get that job done, but using NaNs
> for that would be way cooler and expose unphysical behaviors faster then just
> setting BC's to a number that you think is stupid enough to break the code or
> at least have the decency to make your visualizations look bad.

Don't do that: the proper way is to detect when you output NaNs (because
scanning an array is cheap compared to writing it) and abort (with a diagnostic
perhaps). File libraries like NetCDF will do that for you.

It should be noted that NAG does much more than intel/gnu/pgi there: it will
pin-point the code line that either reads uninitialized data or produces NaNs
because of invalid computations. Both of which must be avoided in a program that
follows the Fortran standard.

Regards, Thomas


robin....@gmail.com

unread,
Jul 5, 2018, 3:47:39 AM7/5/18
to
On Saturday, June 30, 2018 at 10:25:31 PM UTC+10, Lisa Lowe wrote:
> Sorry, I think the question is “how do I assign NaN”. Zero over zero is NaN, integer not float (0/0)

How will 0/0 give a NaN? (integer?) At best, you'd expect
integer division by zero.

jfh

unread,
Jul 5, 2018, 9:59:42 PM7/5/18
to
Lisa should have used the real zero hence 0.0/0.0. Integer NaN does not exist in Fortran. In my computer all 2**n possible n-bit patterns are valid integers, from -2**(n-1) to +2**(n-1)-1, where n is the bit_size of an integer kind known to the compiler, e.g. one of 8,16,32,64,128 if I'm using gfortran, or one of 8,16,32,64 if another compiler.

robin....@gmail.com

unread,
Jul 6, 2018, 2:14:26 AM7/6/18
to
On Friday, July 6, 2018 at 11:59:42 AM UTC+10, jfh wrote:
> On Thursday, July 5, 2018 at 7:47:39 PM UTC+12, robin....@gmail.com wrote:
> > On Saturday, June 30, 2018 at 10:25:31 PM UTC+10, Lisa Lowe wrote:
> > > Sorry, I think the question is “how do I assign NaN”. Zero over zero is NaN, integer not float (0/0)
> >
> > How will 0/0 give a NaN? (integer?) At best, you'd expect
> > integer division by zero.
>
> Lisa should have used the real zero hence 0.0/0.0.

Of course, but she explicitly stated "integer not real"

> Integer NaN does not exist in Fortran.

But some systems use the largest negative integer value
to signify uninitialised.

> In my computer all 2**n possible n-bit patterns are valid integers, from -2**(n-1) to +2**(n-1)-1, where n is the bit_size of an integer kind known to the compiler, e.g. one of 8,16,32,64,128 if I'm using gfortran, or one of 8,16,32,64 if another compiler.

An integer size of 8 is not always available.

Jack Potter

unread,
Jul 7, 2018, 2:34:53 AM7/7/18
to
U.S.A /CA Call//Text/ WhatsApp:+1 8304848039 Vicodin, Valium, Hydrocodone, Adderal, Xanax, Steroids,Vicodin, Valium, Hydrocodone, Adderal, Xanax, Steroids

Order Original pain medications, anxiety management medications and
injections, ED pills and Cough Syrups and many others at attractive prices.
email at:

Cal USA :+18304848039

SHIPPING:
Stealth Package
- Vacuum sealed thick plastic
- Return address.
- Express Delivery with tracking

Shipping time varies for each country.
But all deliveries are done within 1 to 3 business days.
Delivery guaranteed!!

Xanax 1 mg ( blue Ksalol)
Xanax 1 mg Upjohn footbals
Xanax 2 mg ( Pfizer LongBars)
Xanax Alprazolam 1mg Parke Davis
AYURVEDIC UREA GROW TALLER HERB, LIQUID AND POWDER.
Calypsol 500mg/10ml, Anesket 1000mg/10ml
Medical Marijuana
Oxycodone 30mg
Oxycontin 40mg
Roxicodone 30mg
Diazepam Valium 10mg
Subutex 8mg
Suboxone 8mg
Ritalin 40mg
Adderall 30mg
Mandrax (Quaalude) 300mg
Tramadol 100mg
Percocet 10mg
Oxynorm 20mg
Vicodin 500mg
Modafinil Nootropics
Ecstasy (Blue Androids)
Ketamine
MDMA
LSD
Fentalyn patches
Nembutal
Klonopin
Ativan
KCN
Seconal
Dilaud , id
AMBIEN
Oxycontin
Percocet
Roxicodon , e
Valium
Adderall
Norco
Hydrocodone
suboxone
truvada 200 mg-300 mg
subutex
watson 540
WATSON 325 10MG
WATSON 853 10MG
Norco
Ambien
DNP (2,4-Dinitrophenol) 100 mg Capsules
METHADONE 10MG, 40MG WAFERS
ACTAVIS PROMETHAZINE
Quaaludes - Methaquallone pills
Growth Hormones
Anabolic Steroid

Here below is the list of oil we have in stock to offer
( Shatter )
(wax )
( Hash )
( afghani oil )
(organic hemp o il =)
( BHO )
(Crumble )
Here below are the strains we have to offer
( Og kush )
( Sour diesel )
( white widow )
( super silver haze )
( jack herer )
( Alaskan thunder fuck )
( green crack = )
( Alien trainwreck )
( pineapple express )
( LSD )
( Afghani kush )
(G13 ) a
(Ak 47)
(Blueberry Kush )

Delivery & quality Guaranteed 100%.
Express Delivery Available with UPS,FedEx,
Tracking numbers available with references.
Shipping secure and discreet
Delivery time. -1 day within U.S.A 2 days out of U.S
Payment Method:By Western Union, Bitcoin, Moneygram, Paypal for bulk order, fast delivery.



U.S.A /CA Call//Text:+1 8304848039


Brian Salter-Duke

unread,
Jul 7, 2018, 8:58:28 PM7/7/18
to
This is not exactly anwering the original question. I maintain a large
quantum chemistry program that iterates the energy through a series of
often time-consuming steps. Rarely I get "NaN" for the energy at the first
step and then it continues to iterate and never converges. This code:-

SUBROUTINE STOPNAN(X)
IMPLICIT NONE
DOUBLE PRECISION X,ZERO
DATA ZERO/0.0D0/
IF (.NOT.(X.LE.ZERO).AND..NOT.(X.GE.ZERO)) THEN
WRITE(*,*) "STOP ON ",X
CALL ABRTVB()
ENDIF
RETURN
END

is called at the end of every iteration and aborts if NaN is found
and does nothing otherwise. Is this the best way to do it?

Brian.

--
Brian Salter-Duke Carnegie, Victoria, Australia
My real address is brian(DOT)james(DOT)duke(AT)gmail(DOTcom
Use this for reply or followup
"A good programmer can write Fortran in any language"

Dominik Gronkiewicz

unread,
Jul 8, 2018, 10:57:28 AM7/8/18
to
Check out the ieee_is_nan function -- should do the trick.

Brian Salter-Duke

unread,
Jul 8, 2018, 6:35:53 PM7/8/18
to
On Sun, 8 Jul 2018 07:57:26 -0700 (PDT), Dominik Gronkiewicz <gro...@gmail.com> wrote:
> W dniu niedziela, 8 lipca 2018 02:58:28 UTC+2 użytkownik Brian Salter-Duke napisał:
>> This is not exactly anwering the original question. I maintain a large
>> quantum chemistry program that iterates the energy through a series of
>> often time-consuming steps. Rarely I get "NaN" for the energy at the first
>> step and then it continues to iterate and never converges. This code:-
>>
>> SUBROUTINE STOPNAN(X)
>> IMPLICIT NONE
>> DOUBLE PRECISION X,ZERO
>> DATA ZERO/0.0D0/
>> IF (.NOT.(X.LE.ZERO).AND..NOT.(X.GE.ZERO)) THEN
>> WRITE(*,*) "STOP ON ",X
>> CALL ABRTVB()
>> ENDIF
>> RETURN
>> END
>>
>> is called at the end of every iteration and aborts if NaN is found
>> and does nothing otherwise. Is this the best way to do it?
>>
>> Brian.
>>
>
> Check out the ieee_is_nan function -- should do the trick.

Thanks. That is good. I had not come across it. Is there a source that
says which compilers support it and which do not? I found a link that said
gfortan 4.7 did not support it. I want a way that works over at least the
range of widely available compilers. I will do some tests.

N.H. Veldhuijzen

unread,
Jul 9, 2018, 10:45:30 AM7/9/18
to
Hello all,

In my days, I used to fill a variable with the binary constant
'11111111111111111111111111111111' in Compaq Fortran. It worked. (ISNAN
returned .TRUE.)

Best wishes,
NHVELDH

Op 09-06-18 om 22:06 schreef Dominik Gronkiewicz:

Dominik Gronkiewicz

unread,
Jul 10, 2018, 10:35:48 AM7/10/18
to
Unfortunately, I do not have such information. I usually assume that anything supported by the latest version of gfortran minus one can be considered safe to use, but I never needed to target old systems. You could temporarily use preprocessing to engage legacy solution if gfortran version is less than 5, until gfortran 4.x dies completely (I believe Ubuntu 14.04 still has this version and is supported until next year).

FortranFan

unread,
Jul 10, 2018, 11:17:49 AM7/10/18
to
On Sunday, July 8, 2018 at 6:35:53 PM UTC-4, Brian Salter-Duke wrote:

> ..
>
> Thanks. That is good. I had not come across it. Is there a source that
> says which compilers support it and which do not? I found a link that said
> gfortan 4.7 did not support it. I want a way that works over at least the
> range of widely available compilers. I will do some tests.
> ..


@Brian Salter-Duke,

Look at the gfortran site if that's your main compiler:
https://gcc.gnu.org/wiki/GFortran/News#GCC5

It says support for the IEEE features (introduced in standard Fortran since the 2003 revision) began with gfortran 5.

Also look at this site, especially the PDF link for Fortran 2003 and 2008 compiler support for details on other compilers:
https://www.fortranplus.co.uk/fortran-information/
0 new messages