PEP 228 – 重新设计 Python 的数值模型
- 作者:
- Moshe Zadka <moshez at zadka.site.co.il>, Guido van Rossum <guido at python.org>
- 状态:
- 已撤回
- 类型:
- 标准跟踪
- 创建日期:
- 2000年11月4日
- 发布历史:
撤回
本 PEP 已撤回,转而支持 PEP 3141。
摘要
目前,Python 的数值模型类似于 C 语言的数值模型:存在几种不相关的数值类型,当请求数值类型之间的操作时,会发生强制转换。尽管 C 语言数值模型的原理是它与硬件层面上发生的情况非常相似,但该原理不适用于 Python。因此,尽管 C 程序员可以接受 2/3 == 0
,但许多 Python 程序员会感到惊讶。
注意:根据新闻组最近的讨论,本 PEP 的动机(和细节)需要扩展。
基本原理
在可用性研究中,Python 最不人性化的一个方面是整数除法返回除法结果的向下取整。这使得编写正确的程序变得困难,需要在代码的各个部分进行 float()
转换。Python 的数值模型源于 C 语言,而一个可能更容易使用的模型可以基于对数字的数学理解。
其他数值模型
Perl 的数值模型是只有一种数字类型——浮点数。虽然它一致且表面上不令人惊讶,但它往往有微妙的陷阱。其中之一是打印数字非常棘手,需要正确的四舍五入。在 Perl 中,还有一种模式是所有数字都是整数。这种模式也有其自身的问题,这些问题源于甚至没有近似方法来除以数字并获得有意义的答案。
Python 数值模型的建议接口
虽然附加类型和类将保留强制转换规则,但内置类型系统将只有一个 Python 类型——一个数字。有几件事可以被视为“数字方法”
isnatural() (是否是自然数)
isintegral() (是否是整数)
isrational() (是否是有理数)
isreal() (是否是实数)
iscomplex() (是否是复数)
isexact() (是否是精确数)
显然,如果一个数字对问题 1 到 5 的回答为真,它也会对任何后续问题回答为真。如果 isexact()
不为真,那么任何答案都可能是错误的。(但不是离谱的错误:它接近真实。)
现在,模型对字段操作(+
, -
, /
, *
)承诺两件事
- 如果两个操作数都满足
isexact()
,则结果满足isexact()
。 - 所有字段规则都为真,除了对于不满足
isexact()
的数字,它们可能只是近似真。
这两个规则的一个结果是,所有精确计算都作为(复数)有理数进行:由于字段法则必须成立,那么
(a/b)*b == a
必须成立。
有一个内置函数 inexact()
,它接受一个数字并返回一个良好的近似不精确数字。不精确数字的精度必须至少与使用 IEEE-754 时一样。
几个经典的 Python 函数即使在给定不精确数字时也会返回精确数字:例如,int()
。
强制转换
数字类型不定义 nb_coerce
。任何数字操作槽在接收到 PyNumber
以外的东西时,都会拒绝实现它。
不精确操作
math
模块中的函数被允许对精确值返回不精确结果。但是,它们绝不会返回非实数。cmath
模块中的函数也允许对精确参数返回不精确结果,并且进一步允许对实数参数返回复数结果。
Numerical Python 问题
使用 Numerical Python 的人是为了高性能向量操作。因此,NumPy 应该保留其基于硬件的数值模型。
未解决的问题
哪些数字字面量是精确的,哪些是不精确的?
我们如何处理 IEEE 754 操作?(可能 isnan/isinf 应该是方法)
在 64 位机器上,当比较涉及转换为浮点数时,整数和浮点数之间的比较可能会出错。长整数和浮点数之间的比较也是如此。这可以通过避免转换为浮点数来解决。(Andrew Koenig 提出。)
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0228.rst