220 lines
6.2 KiB
ReStructuredText
220 lines
6.2 KiB
ReStructuredText
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.
|
||
|
||
.. [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
|
||
|
||
|
||
|
||
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:
|