numpy.float128的内部精度是多少?

39 投票
3 回答
41777 浏览
提问于 2025-04-17 11:57

请问 numpy.float128 在内部是用什么精度的呢?是 __float128 还是长双精度(long double)?或者是完全不同的东西?

如果有人知道的话,还有一个后续问题:在C语言中,把 __float128 转换成(16字节的)长双精度是否安全,只会导致精度损失?(这是为了和一个处理长双精度的C库进行接口对接)。

补充说明:针对评论的回复,平台是 'Linux-3.0.0-14-generic-x86_64-with-Ubuntu-11.10-oneiric'。如果 numpy.float128 的精度因平台而异,那对我来说也是很有用的信息!

为了明确,我关心的是 精度,而不是元素的大小。

3 个回答

6

numpy 文档 的总结:

np.longdouble 是根据系统的默认设置来填充的;而 np.float96np.float128 是为了那些需要特定填充的用户提供的。尽管名字上看起来更高级,实际上 np.float96np.float128 提供的精度和 np.longdouble 是一样的,也就是说,在大多数 x86 机器上是 80 位,在标准的 Windows 版本上是 64 位。

59

numpy.longdouble 是指你所使用的 C 编译器所称的 long double 类型。目前,numpy 只支持这种扩展精度的浮点数类型。

在 x86-32 和 x86-64 的系统上,这种类型是 80 位浮点数。在一些特殊的系统上,它可能会有所不同(如果我没记错的话,在 Sparc 系统上,它是实际的 128 位 IEEE 浮点数,而在 PPC 系统上则是 双双精度)。这也可能取决于你使用的操作系统和编译器,比如在 Windows 上的 MSVC 就根本不支持任何扩展精度。

Numpy 还会导出一些像 numpy.float96numpy.float128 这样的名称。具体导出哪个名称取决于你的平台和编译器,但无论你得到的是哪个名称,它们都指的是与 longdouble 相同的底层类型。此外,这些名称可能会让人误解。它们 并不 表示 96 位或 128 位的 IEEE 浮点格式。相反,它们表示的是底层 long double 类型所使用的 对齐位数。举个例子,在 x86-32 上,long double 是 80 位,但为了保持 32 位对齐,会填充到 96 位,因此 numpy 称之为 float96。在 x86-64 上,long double 仍然是相同的 80 位类型,但这次会填充到 128 位以保持 64 位对齐,numpy 称之为 float128。这里并没有额外的精度,只是额外的填充。

建议:忽略 float96/float128 这些名称,直接使用 numpy.longdouble。或者更好的是,除非你有非常强烈的理由,否则最好还是使用双精度(doubles)。它们会更快,更具可移植性等等。

15

建议使用 longdouble 而不是 float128,因为现在 float128 的情况比较混乱。Python 在初始化时会把它转换成 float64

在 numpy 里面,它可以是 double 或 long double。这些定义在 npy_common.h 里,具体取决于你的平台。我不确定你是否可以直接把它包含到你的源代码中。

如果你在算法的这一部分不需要特别高的性能,一个更安全的做法是把它导出为字符串,然后再使用 strold

撰写回答