PEP: 754 Title: IEEE 754 Floating Point Special Values Version:
$Revision$ Last-Modified: $Date$ Author: Gregory R. Warnes
<gregory_r_warnes@groton.pfizer.com> Status: Rejected Type: Standards
Track Content-Type: text/x-rst Created: 28-Mar-2003 Python-Version: 2.3
Post-History:

Rejection Notice

This PEP has been rejected. After sitting open for four years, it has
failed to generate sufficient community interest.

Several ideas of this PEP were implemented for Python 2.6. float('inf')
and repr(float('inf')) are now guaranteed to work on every supported
platform with IEEE 754 semantics. However the eval(repr(float('inf')))
roundtrip is still not supported unless you define inf and nan yourself:

    >>> inf = float('inf')
    >>> inf, 1E400
    (inf, inf)
    >>> neginf = float('-inf')
    >>> neginf, -1E400
    (-inf, -inf)
    >>> nan = float('nan')
    >>> nan, inf * 0.
    (nan, nan)

The math and the sys module also have gained additional features,
sys.float_info, math.isinf, math.isnan, math.copysign.

Abstract

This PEP proposes an API and a provides a reference module that
generates and tests for IEEE 754 double-precision special values:
positive infinity, negative infinity, and not-a-number (NaN).

Rationale

The IEEE 754 standard defines a set of binary representations and
algorithmic rules for floating point arithmetic. Included in the
standard is a set of constants for representing special values,
including positive infinity, negative infinity, and indeterminate or
non-numeric results (NaN). Most modern CPUs implement the IEEE 754
standard, including the (Ultra)SPARC, PowerPC, and x86 processor series.

Currently, the handling of IEEE 754 special values in Python depends on
the underlying C library. Unfortunately, there is little consistency
between C libraries in how or whether these values are handled. For
instance, on some systems "float('Inf')" will properly return the IEEE
754 constant for positive infinity. On many systems, however, this
expression will instead generate an error message.

The output string representation for an IEEE 754 special value also
varies by platform. For example, the expression "float(1e3000)", which
is large enough to generate an overflow, should return a string
representation corresponding to IEEE 754 positive infinity. Python 2.1.3
on x86 Debian Linux returns "inf". On Sparc Solaris 8 with Python 2.2.1,
this same expression returns "Infinity", and on MS-Windows 2000 with
Active Python 2.2.1, it returns "1.#INF".

Adding to the confusion, some platforms generate one string on
conversion from floating point and accept a different string for
conversion to floating point. On these systems :

    float(str(x))

will generate an error when "x" is an IEEE special value.

In the past, some have recommended that programmers use expressions
like:

    PosInf = 1e300**2
    NaN = PosInf/PosInf

to obtain positive infinity and not-a-number constants. However, the
first expression generates an error on current Python interpreters. A
possible alternative is to use:

    PosInf = 1e300000
    NaN = PosInf/PosInf

While this does not generate an error with current Python interpreters,
it is still an ugly and potentially non-portable hack. In addition,
defining NaN in this way does solve the problem of detecting such
values. First, the IEEE 754 standard provides for an entire set of
constant values for Not-a-Number. Second, the standard requires that :

    NaN != X

for all possible values of X, including NaN. As a consequence :

    NaN == NaN

should always evaluate to false. However, this behavior also is not
consistently implemented. [e.g. Cygwin Python 2.2.2]

Due to the many platform and library inconsistencies in handling IEEE
special values, it is impossible to consistently set or detect IEEE 754
floating point values in normal Python code without resorting to
directly manipulating bit-patterns.

This PEP proposes a standard Python API and provides a reference module
implementation which allows for consistent handling of IEEE 754 special
values on all supported platforms.

API Definition

Constants

NaN

    Non-signalling IEEE 754 "Not a Number" value

PosInf

    IEEE 754 Positive Infinity value

NegInf

    IEEE 754 Negative Infinity value

Functions

isNaN(value)

    Determine if the argument is an IEEE 754 NaN (Not a Number) value.

isPosInf(value)

    Determine if the argument is an IEEE 754 positive infinity value.

isNegInf(value)

    Determine if the argument is an IEEE 754 negative infinity value.

isFinite(value)

    Determine if the argument is a finite IEEE 754 value (i.e., is not
    NaN, positive, or negative infinity).

isInf(value)

    Determine if the argument is an infinite IEEE 754 value (positive or
    negative infinity)

Example

(Run under Python 2.2.1 on Solaris 8.)

>>> import fpconst >>> val = 1e30000 # should be cause overflow and
result in "Inf" >>> val Infinity >>> fpconst.isInf(val) 1 >>>
fpconst.PosInf Infinity >>> nval = val/val # should result in NaN >>>
nval NaN >>> fpconst.isNaN(nval) 1 >>> fpconst.isNaN(val) 0

Implementation

The reference implementation is provided in the module "fpconst"[1],
which is written in pure Python by taking advantage of the "struct"
standard module to directly set or test for the bit patterns that define
IEEE 754 special values. Care has been taken to generate proper results
on both big-endian and little-endian machines. The current
implementation is pure Python, but some efficiency could be gained by
translating the core routines into C.

Patch 1151323 "New fpconst module"[2] on SourceForge adds the fpconst
module to the Python standard library.

References

See http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html for
reference material on the IEEE 754 floating point standard.

Copyright

This document has been placed in the public domain.



  Local Variables: mode: indented-text indent-tabs-mode: nil
  sentence-end-double-space: t fill-column: 70 End:

[1] Further information on the reference package is available at
http://research.warnes.net/projects/rzope/fpconst/

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