PEP 242 – 数值类型
- 作者:
- Paul F. Dubois <paul at pfdubois.com>
- 状态:
- 已撤回
- 类型:
- 标准跟踪
- 创建日期:
- 2001年3月17日
- Python 版本:
- 2.2
- 发布历史:
- 2001年4月17日
目录
摘要
本提案为用户提供了可选的控制数值计算的精度和范围的功能,从而使计算可以一次编写,并在任何地方运行,且至少具有所需的精度和范围。它与现有代码向后兼容。十进制字面量的含义得到了澄清。
基本原理
目前,除了 Fortran 90 之外,所有语言都无法以可移植的方式编写使用浮点数的程序,并且无论平台如何都能得到大致相同的答案,或者如果无法做到则拒绝编译。Python 目前只有一种浮点类型,在 C 实现中相当于 C double。
不存在与单精度或四精度浮点数对应的类型。直接引入此类类型会使语言复杂化,并且其后续使用将不可移植。本提案类似于 Fortran 90 的“kind”解决方案,并适应了 Python 环境。有了这个功能,整个计算可以通过更改一行代码从一个精度级别切换到另一个精度级别。如果所需精度在特定机器上不存在,程序将失败而不是得到错误的答案。由于以这种风格进行编码将涉及早期调用将失败的例程,这是仅次于不编译的最佳选择。
支持的整数和浮点数类型
复数将在下面单独处理,因为 Python 可以不包含复数进行构建。
每个 Python 编译器都可以定义任意数量的整数和浮点数“类型”,但它必须至少支持两种整数类型,对应于现有的 int 和 long,并且必须至少支持一种浮点数类型,相当于当前的 float。
这些所需类型的范围和精度与目前一样,取决于处理器,但“长整数”类型除外,它可以保存任意整数。
内置函数 int()、long() 和 float() 将输入转换为这些默认类型,就像现在一样。(请注意,Unicode 字符串实际上是不同“类型”的字符串,并且足够了解的人可能会扩展此 PEP 以涵盖该情况。)
在每种类型(整数、浮点数)中,编译器支持一个线性有序的类型集合,其排序由容纳增加范围和/或精度的数字的能力决定。
类型对象
在名为“kinds”的模块中定义了两个新的标准函数。它们返回称为类型对象的可调用对象。每个整数或浮点类型对象 f 都具有签名 result = f(x),每个复数类型对象都具有签名 result = f(x, y=0.)。
int_kind(n)- 对于整数参数
n >= 1,返回一个可调用对象,其结果是可以在开区间 (-10**n,10**n) 中保存整数的整数类型。该类型对象接受包括长整数在内的整数参数。如果n == 0,则返回对应于 Python 字面量 0 的类型对象。 float_kind(nd, n)- 对于
nd >= 0和n >= 1,返回一个可调用对象,其结果是浮点类型,它将保存具有至少 nd 位精度和闭区间[-n, n]中以 10 为底的指数的浮点数。该类型对象接受整数或浮点数参数。如果 nd 和 n 都为零,则返回对应于 Python 字面量 0.0 的类型对象。
编译器将返回对应于该类型可用类型集中具有所需属性的最小类型对象。如果给定实现中不存在具有所需属性的类型,则会抛出 OverflowError 异常。类型函数将其参数转换为目标类型,但如果结果不适合目标类型的范围,则会抛出 OverflowError 异常。
除了可调用行为之外,类型对象还具有提供相关类型特征的属性。
name是类型的名称。标准类型称为 int、long、double。typecode是一个单字母字符串,适用于与Numeric或模块array一起使用以形成此类型的数组。标准类型的 typecode 分别是 'i'、'O'、'd'。- 整数类型具有以下附加属性:
MAX,等于此类型的最大允许整数,或长整数类型的None。MIN,等于此类型的最小允许整数,或长整数类型的None。 - 浮点类型具有以下附加属性,其属性值等于标准头文件“float.h”中相应 C 类型的对应值。
MAX、MIN、DIG、MANT_DIG、EPSILON、MAX_EXP、MAX_10_EXP、MIN_EXP、MIN_10_EXP、RADIX、ROUNDS(== float.h 中的FLT_RADIX,FLT_ROUNDS)。这些值除了MAX、MIN和EPSILON之外都是整数类型,它们是该类型对应的 Python 浮点类型。
kinds 模块的属性
int_kinds 是可用整数类型的列表,按从低到高排序。根据定义,int_kinds[-1] 是长整数类型。
float_kinds 是可用浮点类型的列表,按从低到高排序。
default_int_kind 是对应于 Python 字面量 0 的类型对象
default_long_kind 是对应于 Python 字面量 0L 的类型对象
default_float_kind 是对应于 Python 字面量 0.0 的类型对象
复数
如果支持,复数的实部和虚部是具有相同类型的浮点数。如果 Python 编译器支持复数,则它必须支持其支持的每种浮点类型的复数模拟。
如果支持复数,则以下内容可在 kinds 模块中使用
complex_kind(nd, n)- 返回一个可调用对象,其结果是复数类型,它将保存一个复数,其每个分量(.real、.imag)都属于
float_kind(nd, n)类型。该类型对象将接受一个任意整数、实数或复数类型的参数,或两个整数或实数参数。
complex_kinds 是可用复数类型的列表,按从低到高排序。
default_complex_kind 是对应于 Python 字面量 0.0j 的类型对象。此类型的名称是 doublecomplex,其 typecode 是 'D'。
复数类型对象具有这些附加属性
floatkind 是相应浮点类型的类型对象。
示例
在 myprecision.py 模块中
import kinds
tinyint = kinds.int_kind(1)
single = kinds.float_kind(6, 90)
double = kinds.float_kind(15, 300)
csingle = kinds.complex_kind(6, 90)
在我的其余代码中
from myprecision import tinyint, single, double, csingle
n = tinyint(3)
x = double(1.e20)
z = 1.2
# builtin float gets you the default float kind, properties unknown
w = x * float(x)
# but in the following case we know w has kind "double".
w = x * double(z)
u = csingle(x + z * 1.0j)
u2 = csingle(x+z, 1.0)
请注意,通过更改 myprecision.py 中的参数,整个代码如何可以更改为更高的精度。
评论:请注意,您不能保证 single != double;但您可以保证 double(1.e20) 将保存一个具有 15 位十进制精度且范围高达 10**300 的数字,否则 float_kind 调用将失败。
未解决的问题
目前尚未提出任何未决问题。
版权
本文档已置于公共领域。
来源:https://github.com/python/peps/blob/main/peps/pep-0242.rst