Mailing List Archive

possible bug in 1.5.1
I am using python to import a SAS database into a
relational database and I'm running into some trouble
with the real number Infinity. I've had trouble with
it before... SAS uses -Infinity to signal exceptional
cases.

One of my functions tests to a Infinity field:

Infinity=1e1000
if rec['HC4']==Infinity: do_something

The code fails because *sometimes* Infinity takes
value Inf and *sometimes* it takes value 0.0...
I've also added the line

print 1e1000

and it sometimes print Inf and sometimes print 0.0.

How can I create a Infinite float in python with
certainty? I'm using a RedHat 5.2 system on Intel.


Many thanks and please reply to

jean@stat.ubc.ca

--
Jean Meloche
possible bug in 1.5.1 [ In reply to ]
[Jean Meloche]
> ...
> The code fails because *sometimes* Infinity takes
> value Inf and *sometimes* it takes value 0.0...
> I've also added the line
>
> print 1e1000
>
> and it sometimes print Inf and sometimes print 0.0.
>
> How can I create a Infinite float in python with
> certainty? I'm using a RedHat 5.2 system on Intel.

You can't with certainty -- Python is not IEEE-754 aware, neither are K&R or
ANSI C (in terms of which Python is implemented), and not all HW supports
infinities anyway.

What you can do is save away the attached as (e.g.) ieee.py, then in your
code do

from ieee import PINF # positive infinity, if it exists

in the modules that need a plus infinity (similarly it exports constants for
minus infinity, plus and minus zero, and a generic quiet NaN). The module
does about the best that can be done of creating these things in a portable
way from within Python, and raises an error if it can't.

Note that whether "print ieee.PINF" *prints* "Inf" is entirely up to your
platform's libc (or equivlalent); e.g., under Win95 it prints "1.#INF", and
ieee.NAN prints "-1.#IND". There's also no guarantee that those strings can
be read in and converted back to float correctly by your platform's libc.

BTW, due to vagaries in IEEE comparison semantics as implemented by your C,
this module may raise a bogus error about NaNs. Let me know if it does, and
we'll find some other way to spell it. This can't be out-thought in
advance, alas, since IEEE C bindings are not yet standardized, and e.g. MS's
C doesn't even generate IEEE-aware comparison code on Pentium platforms
(where the HW supports it directly). IOW, this module works under Windows
Python by contrived accident.

floating-point-is-the-devil's-finest-achievement<wink>-ly y'rs - tim
possible bug in 1.5.1 [ In reply to ]
[Tim]
> ...
> What you can do is save away the attached as (e.g.) ieee.py, then
> in your code do
>
> from ieee import PINF # positive infinity, if it exists

Oops -- the attachment got lost due to a rounding error <wink>. Here:

def _make_inf():
x = 2.0
x2 = x * x
i = 0
while i < 100 and x != x2:
x = x2
x2 = x * x
i = i + 1
if x != x2:
raise ValueError("This machine's floats go on forever!")
return x

PINF = _make_inf()
MINF = -PINF
NAN = PINF - PINF
if 1.0 + NAN == 1.0:
raise ValueError("This machine doesn't have NaNs, "
"'overflows' to a finite number, "
"or is 754-conformant but is using "
"a goofy rounding mode.")
PZERO = 0.0
MZERO = -PZERO