By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,767 Members | 1,228 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,767 IT Pros & Developers. It's quick & easy.

test for nan

P: n/a

I have a C extension module that is returning some doubles. When the
doubles get out of range, the numbers print as 'nan'.

Is there a better way to test for NaN than

str(p1)=='nan'

where p1 is a float?

python2.3

Thanks,
John Hunter

Jul 18 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
At some point, John Hunter <jd******@ace.bsd.uchicago.edu> wrote:
I have a C extension module that is returning some doubles. When the
doubles get out of range, the numbers print as 'nan'.

Is there a better way to test for NaN than

str(p1)=='nan'

where p1 is a float?


The string representation of NaN is system-dependent. On Windows it's
something like #NaN. You'd be better off with Jeff Epler's suggestion
of wrapping isnan() (since you already have a C extension module, you
could through it in there).

If you're on something that uses IEEE floating-point representations,
something like this in pure python should work:

import struct
def isnan(x):
s = struct.pack('d', x)
if struct.pack('h', 1) == '\x01\x00':
return s == '\x00\x00\x00\x00\x00\x00\xf0\x7f':
else:
return s == '\x7f\xf8\x00\x00\x00\x00\x00\x00':

The test for endianness is there since struct.unpack('<d', x)
complains that frexp() is out of range.

--
|>|\/|<
/--------------------------------------------------------------------------\
|David M. Cooke
|cookedm(at)physics(dot)mcmaster(dot)ca
Jul 18 '05 #2

P: n/a
John Hunter <jd******@ace.bsd.uchicago.edu> writes:
I have a C extension module that is returning some doubles. When the
doubles get out of range, the numbers print as 'nan'.

Is there a better way to test for NaN than

str(p1)=='nan'

where p1 is a float?


I'd hope so: that's exceeding unportable. Of course, all things to do
with nans are unportable, so you're going to have to tell us more of
your requirements...

Cheers,
mwh

--
I have *both* hands clapping, but I'm still not sure it's a sound.
When I tried deciding if it were a sound while clapping only one
hand, I fell off my chair.
-- Peter Hansen, Zen master, comp.lang.python
Jul 18 '05 #3

P: n/a
John Hunter wrote:
I have a C extension module that is returning some doubles. When the
doubles get out of range, the numbers print as 'nan'.

Is there a better way to test for NaN than

str(p1)=='nan'

where p1 is a float?

python2.3

Thanks,
John Hunter


As far as I know NaN is th only value that yields false when compared
to itself. This leads to

def isNaN(x):
return (x == x) == False

Mit freundlichen Gruessen,

Peter Maas

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24
Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de
-------------------------------------------------------------------
Jul 18 '05 #4

P: n/a
Peter Maas wrote:
John Hunter wrote:
Is there a better way to test for NaN than

str(p1)=='nan'

where p1 is a float?

[...]
As far as I know NaN is th only value that yields false when compared
to itself. This leads to

def isNaN(x):
return (x == x) == False


Shorter:

def isNaN(x):
return x != x

Mit freundlichen Gruessen,

Peter Maas

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24
Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de
-------------------------------------------------------------------
Jul 18 '05 #5

P: n/a
Peter Maas wrote:
As far as I know NaN is th only value that yields false when compared
to itself. This leads to

def isNaN(x):
return (x == x) == False


That is not portable:

Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
nan = float("nan")
nan != nan

False
Peter

Jul 18 '05 #6

P: n/a
Peter Otten wrote:
def isNaN(x):
return (x == x) == False

That is not portable:

Python 2.3.3 (#1, Jan 3 2004, 13:57:08)
[GCC 3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
nan = float("nan")
nan != nan


False


Thanks for correction. I firmly believed that NaN != NaN -> True
was a property of IEEE 754 and of all software using this standard.
For gcc/Linux you could use

def isNaN(x):
return (x == 0) and (x == 1)

and utilize sys.platform. :)

Mit freundlichen Gruessen,

Peter Maas

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24
Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de
-------------------------------------------------------------------
Jul 18 '05 #7

P: n/a
Peter Maas <fp********@netscape.net> writes:
John Hunter wrote:
I have a C extension module that is returning some doubles. When the
doubles get out of range, the numbers print as 'nan'.
Is there a better way to test for NaN than
str(p1)=='nan'
where p1 is a float?
python2.3
Thanks,
John Hunter

As far as I know NaN is th only value that yields false when
compared to itself.


There can be more than one NaN, by the way.
This leads to

def isNaN(x):
return (x == x) == False


This will work with 2.3 on Windows (I believe), current CVS on Windows
(if compiled with VC7.1), current CVS on Linux (assuming an even
vaguely recent gcc), but not current CVS on Windows compiled with VC6,
nor Python 2.3 on Linux/gcc. Confused yet?

Other platforms I haven't the faintest idea about.

Cheers,
mwh

--
41. Some programming languages manage to absorb change, but
withstand progress.
-- Alan Perlis, http://www.cs.yale.edu/homes/perlis-alan/quotes.html
Jul 18 '05 #8

P: n/a
Peter Maas wrote:
def isNaN(x):
return (x == 0) and (x == 1)


This works here. Do you have an idea what the rationale behind this
behaviour (i. e. any number == nan) is?

Peter
Jul 18 '05 #9

P: n/a
>>>>> "Michael" == Michael Hudson <mw*@python.net> writes:

Michael> This will work with 2.3 on Windows (I believe), current
Michael> CVS on Windows (if compiled with VC7.1), current CVS on
Michael> Linux (assuming an even vaguely recent gcc), but not
Michael> current CVS on Windows compiled with VC6, nor Python 2.3
Michael> on Linux/gcc. Confused yet?

Fortunately I only need linux for this particular app, so I can use
one of the platform dependent solutions, but the bevy of proposed
solutions and gotchas have definitely been interesting.

Out of curiosity, are there any platforms where this is known to fail?

def is_nan(x):
return str(x).lower().find('nan')>=0

JDH

Jul 18 '05 #10

P: n/a
John Hunter wrote:
Out of curiosity, are there any platforms where this is known to fail?

def is_nan(x):
return str(x).lower().find('nan')>=0


Yes...

Python 2.3.3 (#51, Dec 18 2003, 20:22:39) [MSC v.1200 32 bit (Intel)] on
win32

IDLE 1.0.2
def is_nan(x): return str(x).lower().find('nan') >= 0
inf=float('1e9999')
inf 1.#INF nan=inf-inf
is_nan(nan) False nan

-1.#IND

--
"Codito ergo sum"
Roel Schroeven
Jul 18 '05 #11

P: n/a
Michael Hudson wrote:
There can be more than one NaN, by the way.


I know that but if all NaNs have the same distinct algorithmic behaviour
that's not a problem.
This leads to

def isNaN(x):
return (x == x) == False

This will work with 2.3 on Windows (I believe), current CVS on Windows
(if compiled with VC7.1), current CVS on Linux (assuming an even
vaguely recent gcc), but not current CVS on Windows compiled with VC6,
nor Python 2.3 on Linux/gcc. Confused yet?


No:

def isNaN1(x):
return x != x

def isNaN2(x):
return (x == 0) and (x == 1)

if sys.platform == 'win32' and '2.3' in sys.version:
isNaN = isNaN1
elif sys.platform == 'win32' and 'good_CVS_VC_stuff' in sys.version:
isNaN = isNaN1
elif sys.platform == 'win32' and 'bad_CVS_VC_stuff' in sys.version:
isNaN = isNaN2
elif sys.platform == 'linux2':
isNaN = isNaN2
else:
raise Exception, "Roll your own isNaN() for platform " \
"%s and version %s\n" % (sys.platform, sys.version)

bad/good_CVS_VC_stuff has to be worked out, don't have the version strings
available.

Mit freundlichen Gruessen,

Peter Maas

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24
Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de
-------------------------------------------------------------------
Jul 18 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.