PEP 754 – IEEE 754 浮点数特殊值
- 作者:
- Gregory R. Warnes <gregory_r_warnes at groton.pfizer.com>
- 状态:
- 已拒绝
- 类型:
- 标准跟踪
- 创建:
- 2003年3月28日
- Python 版本:
- 2.3
- 历史记录:
拒绝通知
此 PEP 已被拒绝。在开放四年后,它未能引起足够的社区兴趣。
此 PEP 的一些想法已在 Python 2.6 中实现。 float('inf')
和 repr(float('inf'))
现在保证可以在每个支持 IEEE 754 语义的平台上工作。但是,除非您自己定义 inf 和 nan,否则 eval(repr(float('inf')))
的往返操作仍不受支持。
>>> inf = float('inf')
>>> inf, 1E400
(inf, inf)
>>> neginf = float('-inf')
>>> neginf, -1E400
(-inf, -inf)
>>> nan = float('nan')
>>> nan, inf * 0.
(nan, nan)
math 和 sys 模块也获得了更多功能,例如 sys.float_info
、math.isinf
、math.isnan
、math.copysign
。
摘要
此 PEP 提出了一种 API,并提供了一个参考模块,用于生成和测试 IEEE 754 双精度特殊值:正无穷大、负无穷大和非数字 (NaN)。
基本原理
IEEE 754 标准定义了一组二进制表示和浮点运算的算法规则。标准中包含一组用于表示特殊值的常量,包括正无穷大、负无穷大和不确定或非数值结果 (NaN)。大多数现代 CPU 都实现了 IEEE 754 标准,包括 (Ultra)SPARC、PowerPC 和 x86 处理器系列。
目前,Python 中对 IEEE 754 特殊值的处理取决于底层的 C 库。不幸的是,C 库在如何或是否处理这些值方面几乎没有一致性。例如,在某些系统上,“float('Inf')”将正确返回正无穷大的 IEEE 754 常量。但是,在许多系统上,此表达式将生成错误消息。
IEEE 754 特殊值的输出字符串表示形式也因平台而异。例如,表达式“float(1e3000)”足够大以生成溢出,应返回对应于 IEEE 754 正无穷大的字符串表示形式。在 x86 Debian Linux 上的 Python 2.1.3 返回“inf”。在带有 Python 2.2.1 的 Sparc Solaris 8 上,此表达式返回“Infinity”,而在带有 Active Python 2.2.1 的 MS-Windows 2000 上,它返回“1.#INF”。
更令人困惑的是,一些平台在从浮点数转换时生成一个字符串,而在转换为浮点数时接受不同的字符串。在这些系统上
float(str(x))
当“x”是 IEEE 特殊值时,将生成错误。
过去,有些人建议程序员使用以下表达式:
PosInf = 1e300**2
NaN = PosInf/PosInf
以获取正无穷大和非数字常量。但是,第一个表达式在当前的 Python 解释器上会生成错误。一个可能的替代方案是使用
PosInf = 1e300000
NaN = PosInf/PosInf
虽然这在当前的 Python 解释器上不会生成错误,但它仍然是一个丑陋且可能不可移植的技巧。此外,以这种方式定义 NaN 并不能解决检测此类值的问题。首先,IEEE 754 标准提供了一整套用于非数字的常量值。其次,标准要求
NaN != X
对于 X 的所有可能值,包括 NaN。因此
NaN == NaN
应始终计算为 false。但是,此行为也没有得到一致的实现。[例如 Cygwin Python 2.2.2]
由于在处理 IEEE 特殊值方面存在许多平台和库的不一致性,因此无法在正常的 Python 代码中一致地设置或检测 IEEE 754 浮点值,而不诉诸直接操作位模式。
此 PEP 提出一个标准的 Python API,并提供一个参考模块实现,允许在所有受支持的平台上一致地处理 IEEE 754 特殊值。
API 定义
常量
- NaN
- 非信号 IEEE 754“非数字”值
- PosInf
- IEEE 754 正无穷大值
- NegInf
- IEEE 754 负无穷大值
函数
- isNaN(value)
- 确定参数是否为 IEEE 754 NaN(非数字)值。
- isPosInf(value)
- 确定参数是否为 IEEE 754 正无穷大值。
- isNegInf(value)
- 确定参数是否为 IEEE 754 负无穷大值。
- isFinite(value)
- 确定参数是否为有限的 IEEE 754 值(即,不是 NaN、正无穷大或负无穷大)。
- isInf(value)
- 确定参数是否为无限的 IEEE 754 值(正无穷大或负无穷大)
示例
(在 Solaris 8 上的 Python 2.2.1 下运行。)
>>> 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
实现
参考实现提供在模块“fpconst”[1]中,该模块用纯 Python 编写,利用“struct”标准模块直接设置或测试定义 IEEE 754 特殊值的位模式。已谨慎地生成在大端和小端机器上均产生正确的结果。当前实现是纯 Python,但可以通过将核心例程转换为 C 来提高一些效率。
SourceForge 上的补丁 1151323“新的 fpconst 模块”[2]将 fpconst 模块添加到 Python 标准库中。
参考文献
有关 IEEE 754 浮点标准的参考材料,请参见 http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html。
版权
本文档已归入公有领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0754.rst
上次修改时间: 2023-09-09 17:39:29 GMT