Numpy八重精度浮点数和128位整数。为什么?如何实现?

20
这主要是出于好奇。我注意到numpy测试套件包含了对128位整数的测试,而numerictypes模块引用了int128float256(八倍精度?)和其他类型,在我的机器上似乎没有对应的numpy数据类型。

我的机器是64位的,但我可以使用四倍精度的128位浮点数(但实际上并不行)。我想如果能够在软件中模拟四倍精度浮点数,理论上也可以模拟八倍精度浮点数和128位整数。另一方面,在此之前我从未听说过128位整数或八倍精度浮点数。如果没有相应的dtype,为什么numpy的numerictypes模块中会有对128位整数和256位浮点数的引用,我该如何使用它们?


我猜你理论上可以解决任何32 * n64 * n的精度问题,但我必须说,这些类型仅在测试中实现的事实是令人着迷的。 - Flavian Hautbois
3
请记住,一个 np.float128 通常并没有 128 位的精度 - 它相当于 C 语言的 long double,在 x86 架构下通常有80个比特(详见此处)。 - ali_m
@ali_m 我明白了。今天我又学到了新的东西! - gerrit
1
通常建议使用np.longdouble而不是np.float128,以避免这种混淆。在我看来,如果numpy根本不暴露float128 dtype会更好... - ali_m
2个回答

5
这是一个非常有趣的问题,可能与Python、计算和/或硬件有关。虽然不试图给出完整的答案,但我会尽力回答...首先要注意的是,类型由语言定义,可以与您的硬件架构不同。例如,您甚至可以在8位处理器上使用双精度浮点数。当然,任何算术都涉及多个 CPU 指令,使计算速度变慢。但是,如果您的应用程序需要它,那么它可能是值得的,甚至是必需的(最好晚点做,也比错误好,特别是如果您正在运行模拟,比如桥梁稳定性...)。那么128位精度在哪里需要呢?在这里可以查看wikipedia article...还有一个有趣的细节是,当我们说计算机是64位时,这并没有完全描述硬件。有很多部分可以每个部分都是(并且至少曾经是)不同的位:CPU 中的计算寄存器、内存寻址方案/内存寄存器以及最重要的是从 CPU 到内存的总线。
-算术逻辑单元(ALU)具有执行计算的寄存器。您的机器是64位的(不确定是否也意味着它们可以同时进行2个32位的计算),这显然是此讨论中最相关的数量。很久以前,您可以购买一个协处理器来加速更高精度的计算...
-保存内存地址的寄存器限制了计算机可以直接查看的内存,这就是为什么具有32位内存寄存器的计算机只能查看2 ^ 32字节(或约4 GB)的原因。请注意,对于16位,这变成了65K,非常低。操作系统可以绕过此限制,但不能为单个程序提供,因此32位计算机中的任何程序通常都无法具有超过4GB的内存。

-请注意,这些限制是关于字节而不是位的。这是因为当引用和从内存加载时,我们加载字节。实际上,以这种方式进行,加载一个字节(8位)或8个(64位==计算机总线长度)需要相同的时间。我请求一个地址,然后通过总线一次性获取所有位。在某种体系结构中,所有这些数量可能不是相同的位数。


-3

NumPy非常强大,可以处理比内部CPU表示更大的数字(例如64位)。

在动态类型的情况下,它将数字存储在数组中。它还可以扩展内存块,这就是为什么您可以拥有具有500个数字的整数。这种动态类型称为bignum。在旧版Python中,它是长类型。在较新的Python(3.0+)中,只有长整型,称为int,支持几乎任意数量的数字(-> bignum)。

如果您指定数据类型(例如int32),则需要指定位长度和位格式,即内存中哪些位代表什么。例如:

dt = np.dtype(np.int32)      # 32-bit integer
dt = np.dtype(np.complex128) # 128-bit complex floating-point number

请查看:https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html


1
128位复数是普通的双精度。 - gerrit
2
float32是单精度浮点数,float64是双精度浮点数,float96是扩展型浮点数,float128是扩展精度浮点数。复数有两个分量,即每个分量占用半宽: complex64是单精度复数,complex128是双精度复数。 - MasterControlProgram

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接