Portably generating infinity and NaN

M

Michael Hoffman

What's the best way to portably generate binary floating point infinity
and NaNs? I only know two solutions:

1. Using the fpconst module proposed in IEEE 754, which I believe shifts
bits around.

2. Using an extension module (for example, numarray.ieeespecial will do it).

I thought of using float(Decimal("nan")), but apparently
Decimal.__float__(self) is float(str(self)), which isn't portable.
 
M

Michael Hoffman

Michael said:
2. Using an extension module (for example, numarray.ieeespecial will do
it).

I guess I could always use ctypes as well, and say, get -inf from
libc.log(ctypes.c_double(0.0)). Although we're venturing away from
portable territory then, since specifying how to load libc will be
different on different platforms.
 
R

Robert Kern

Michael said:
What's the best way to portably generate binary floating point infinity
and NaNs? I only know two solutions:

1. Using the fpconst module proposed in IEEE 754, which I believe shifts
bits around.

2. Using an extension module (for example, numarray.ieeespecial will do it).

I thought of using float(Decimal("nan")), but apparently
Decimal.__float__(self) is float(str(self)), which isn't portable.

This is what numpy does (translated from the C):

mul = 1e10
inf = mul
tmp = 0.0
while True:
inf *= mul
if inf == tmp:
break
tmp = inf

nan = inf / inf

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Michael said:
What's the best way to portably generate binary floating point infinity
and NaNs? I only know two solutions:

1. Using the fpconst module proposed in IEEE 754, which I believe shifts
bits around.

2. Using an extension module (for example, numarray.ieeespecial will do
it).

Use the struct module to pack/unpack a double value. On an IEEE 754
system, this should work - on a non-IEEE-754 system, it's not clear
that +/-inf and NaN actually exist.

Regards,
Martin
 
S

skip

Michael> What's the best way to portably generate binary floating point
Michael> infinity and NaNs?

I take it this isn't portable even though it works on Mac, Linux and Solaris
across a number of different Python versions and a couple GCC versions:

% python
Python 2.4.2 (#1, Feb 23 2006, 12:48:31)
[GCC 3.4.1] on sunos5
Type "help", "copyright", "credits" or "license" for more information. '\x00\x00\x80\x7f'

$ python
Python 2.5 (release25-maint:53536, Jan 23 2007, 18:15:37)
[GCC 3.4.6 20060404 (Red Hat 3.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information. '\x00\x00\x80\x7f'

% python
Python 2.6a0 (trunk:54264M, Mar 10 2007, 15:19:48)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information. '\x7f\xc0\x00\x00'

(Note the absence of a demonstration on Windows.) Can't the above be
blessed as the One True Way and wormed around in floatmodule.c for those
platforms where float'ing "NaN" or "Inf" doesn't currently work?

Skip
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

(Note the absence of a demonstration on Windows.) Can't the above be
blessed as the One True Way and wormed around in floatmodule.c for those
platforms where float'ing "NaN" or "Inf" doesn't currently work?

How would you do the worming-around?

Regards,
Martin
 
S

skip

Martin> How would you do the worming-around?

I don't know. On I was just asking. On unixoid systems I sort of assume
you could add tests to the configure script to detect what worked. If
converting the strings works you're done. If not, maybe Robert Kern's numpy
code could be run in the configure script to generate constants for NaN and
Inf that could be used in floatmodule.c. Windows would probably have to be
hard-coded, but except for 32-bit and 64-bit differences it should be the
same all over, yes?

Skip
 
M

Michael Hoffman

Martin> How would you do the worming-around?

I don't know. On I was just asking. On unixoid systems I sort of assume
you could add tests to the configure script to detect what worked. If
converting the strings works you're done. If not, maybe Robert Kern's numpy
code could be run in the configure script to generate constants for NaN and
Inf that could be used in floatmodule.c. Windows would probably have to be
hard-coded, but except for 32-bit and 64-bit differences it should be the
same all over, yes?

If you're going to change CPython to do this, I think adopting PEP 754,
and using the fpconst module would be better than changing how float()
works when called on string literals. The only thing I don't like about
it is the camelcasing of the functions.

http://www.python.org/dev/peps/pep-0754/
 
M

Michael Hoffman

Michael said:
If you're going to change CPython to do this, I think adopting PEP 754,
and using the fpconst module would be better than changing how float()
works when called on string literals. The only thing I don't like about
it is the camelcasing of the functions.

http://www.python.org/dev/peps/pep-0754/

I notice in the tracker, kousu suggested an alternative design, where
the test functions become part of the float type. So you'd have
float.isnan(), float.isfinite(), etc.

http://sourceforge.net/tracker/?func=detail&aid=1151323&group_id=5470&atid=305470
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

I don't know. On I was just asking. On unixoid systems I sort of assume
you could add tests to the configure script to detect what worked. If
converting the strings works you're done. If not, maybe Robert Kern's numpy
code could be run in the configure script to generate constants for NaN and
Inf that could be used in floatmodule.c. Windows would probably have to be
hard-coded, but except for 32-bit and 64-bit differences it should be the
same all over, yes?

I cannot imagine what the constants would look like. For +/-inf, it
might be possible to write down an expression that causes an overflow.
For NaN, I cannot think of such an expression (also, there are many
possible values that are all not-a-number - which of them should be
denoted by float("NaN")?).

Even if you determine at configure time whether or not the C library
already supports strtod("inf") and even if you then special-case
Windows - what do you do with platforms where neither approach works?

In short, I cannot think of a way to do that portably on all platforms
in C. If there was such a way, it probably would have been implemented
long ago.

Regards,
Martin
 
D

Duncan Booth

% python
Python 2.6a0 (trunk:54264M, Mar 10 2007, 15:19:48)
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more
information. '\x7f\xc0\x00\x00'

(Note the absence of a demonstration on Windows.) Can't the above be
blessed as the One True Way and wormed around in floatmodule.c for
those platforms where float'ing "NaN" or "Inf" doesn't currently work?

How about doing the same in reverse to generate the values on Windows? It
should be pretty portable, otherwise the struct module doesn't work as
advertised:
(1.#QNAN, 1.#INF)

This also means you can choose which NaN you generate, although given
that it compares unequal with itself it probably doesn't matter.
 
S

skip

Michael> If you're going to change CPython to do this, I think adopting
Michael> PEP 754, and using the fpconst module would be better than
Michael> changing how float() works when called on string literals.

But PEP 754 will only work for architectures supporting IEEE 754. I realize
that's the vast majority of systems, but aren't there still a few Crays and
VMS machines out there? (Do those architectures support NaN and Inf?)

Skip
 
M

Michael Hoffman

Michael> If you're going to change CPython to do this, I think adopting
Michael> PEP 754, and using the fpconst module would be better than
Michael> changing how float() works when called on string literals.

But PEP 754 will only work for architectures supporting IEEE 754. I realize
that's the vast majority of systems, but aren't there still a few Crays and
VMS machines out there? (Do those architectures support NaN and Inf?)

Will float("NaN") work on these systems? (I don't know.) I guess it
probably works on some system that isn't IEEE 754.
 
P

Paul Rubin

But PEP 754 will only work for architectures supporting IEEE 754. I realize
that's the vast majority of systems, but aren't there still a few Crays and
VMS machines out there? (Do those architectures support NaN and Inf?)

I wouldn't worry about it. There are Python subsystems (like threads) that
don't work on certain OS's, fine, total portability means not being able to
rely on them, and that's ok. I doubt any Crays are still running, or at least
running any numerical code written in Python. Same for VMS.
 
R

Robert Kern

Paul said:
I doubt any Crays are still running, or at least
running any numerical code written in Python.

You are wrong.
Same for VMS.

Also wrong.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
S

Steve Holden

Paul said:
I wouldn't worry about it. There are Python subsystems (like threads) that
don't work on certain OS's, fine, total portability means not being able to
rely on them, and that's ok. I doubt any Crays are still running, or at least
running any numerical code written in Python. Same for VMS.

Think again.

regards
Steve
 
S

skip

Michael> Will float("NaN") work on these systems? (I don't know.) I
Michael> guess it probably works on some system that isn't IEEE 754.

My thought was that in configure you could test if strtof("NaN") and
strtof("Inf") worked. If not, calculate the necessary bit patterns at that
point and use conditional compilation in floatmodule.c to generate them.

Skip
 
D

Dennis Lee Bieber

I wouldn't worry about it. There are Python subsystems (like threads) that
don't work on certain OS's, fine, total portability means not being able to
rely on them, and that's ok. I doubt any Crays are still running, or at least
running any numerical code written in Python. Same for VMS.

Whilst an abundance of Axes may not exist, VMS, in one release or
another, was still in heavy usage on various "mainframes" (when did a
large Alpha system grow from "super mini" to "mainframe" <G>) as of four
years ago, when I'd been released from a program... I doubt if the
government could justify the cost of porting that major application
suite to some other processor/OS family (though I will confess to
hearsay that the project was supposed to be porting all the graphical
interface stuff to Java -- probably to get rid of stuff that was
specific to DEC Windows, HPUX, and Solar is and allow any workstation to
be used for display -- but last I'd heard was that the remains of that
project had received a stop-work order a year later, due to lack of
progress/overruns).
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
M

Michael Hoffman

Paul said:
I wouldn't worry about it. There are Python subsystems (like threads) that
don't work on certain OS's, fine, total portability means not being able to
rely on them, and that's ok. I doubt any Crays are still running, or at least
running any numerical code written in Python. Same for VMS.

Do these systems provide infinities or NaN? If so, then fpconst could be
extended to include them.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top