2003-04-12 09:39:34 -04:00
|
|
|
|
PEP: 754
|
|
|
|
|
Title: IEEE 754 Floating Point Special Values
|
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2003-05-14 18:23:07 -04:00
|
|
|
|
Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com> (Pfizer, Inc.)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standard Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 28-Mar-2003
|
|
|
|
|
Python-Version: 2.3
|
|
|
|
|
Post-History:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
This PEP proposes an API and a provides a reference module that
|
|
|
|
|
generates and tests for IEEE 754 double-precision special values:
|
2003-05-14 18:23:07 -04:00
|
|
|
|
positive infinity, negative infinity, and not-a-number (NaN).
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
2003-05-14 18:23:07 -04:00
|
|
|
|
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.
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
|
|
|
|
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::
|
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
PosInf = 1e300**2
|
|
|
|
|
NaN = PosInf/PosInf
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
|
|
|
|
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::
|
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
PosInf = 1e300000
|
|
|
|
|
NaN = PosInf/PosInf
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
|
|
|
|
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
|
2003-05-14 18:23:07 -04:00
|
|
|
|
Non-signalling IEEE 754 "Not a Number" value
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
PosInf
|
2003-04-12 09:39:34 -04:00
|
|
|
|
IEEE 754 Positive Infinity value
|
|
|
|
|
|
|
|
|
|
NegInf
|
|
|
|
|
IEEE 754 Negative Infinity value
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Functions
|
|
|
|
|
---------
|
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
isNaN(value)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
Determine if the argument is a IEEE 754 NaN (Not a Number) value.
|
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
isPosInf(value)
|
|
|
|
|
Determine if the argument is a IEEE 754 positive infinity value.
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
isNegInf(value)
|
|
|
|
|
Determine if the argument is a IEEE 754 negative infinity value.
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
isFinite(value)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
Determine if the argument is an finite IEEE 754 value (i.e., is
|
2003-05-14 18:23:07 -04:00
|
|
|
|
not NaN, positive, or negative infinity).
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
2003-05-14 18:23:07 -04:00
|
|
|
|
isInf(value)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
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
|
2003-05-14 18:23:07 -04:00
|
|
|
|
>>> fpconst.isInf(val)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
1
|
2003-05-14 18:23:07 -04:00
|
|
|
|
>>> fpconst.PosInf
|
2003-04-12 09:39:34 -04:00
|
|
|
|
Infinity
|
|
|
|
|
>>> nval = val/val # should result in NaN
|
|
|
|
|
>>> nval
|
|
|
|
|
NaN
|
2003-05-14 18:23:07 -04:00
|
|
|
|
>>> fpconst.isNaN(nval)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
1
|
2003-05-14 18:23:07 -04:00
|
|
|
|
>>> fpconst.isNaN(val)
|
2003-04-12 09:39:34 -04:00
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2004-12-11 13:34:25 -05:00
|
|
|
|
http://research.warnes.net/projects/rzope/fpconst/
|
2003-04-12 09:39:34 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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:
|