numpy.float128的内部精度是多少?
请问 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 个回答
从 numpy 文档 的总结:
np.longdouble
是根据系统的默认设置来填充的;而np.float96
和np.float128
是为了那些需要特定填充的用户提供的。尽管名字上看起来更高级,实际上np.float96
和np.float128
提供的精度和np.longdouble
是一样的,也就是说,在大多数 x86 机器上是 80 位,在标准的 Windows 版本上是 64 位。
numpy.longdouble
是指你所使用的 C 编译器所称的 long double
类型。目前,numpy 只支持这种扩展精度的浮点数类型。
在 x86-32 和 x86-64 的系统上,这种类型是 80 位浮点数。在一些特殊的系统上,它可能会有所不同(如果我没记错的话,在 Sparc 系统上,它是实际的 128 位 IEEE 浮点数,而在 PPC 系统上则是 双双精度)。这也可能取决于你使用的操作系统和编译器,比如在 Windows 上的 MSVC 就根本不支持任何扩展精度。
Numpy 还会导出一些像 numpy.float96
或 numpy.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)。它们会更快,更具可移植性等等。
建议使用 longdouble
而不是 float128,因为现在 float128 的情况比较混乱。Python 在初始化时会把它转换成 float64
。
在 numpy 里面,它可以是 double 或 long double。这些定义在 npy_common.h
里,具体取决于你的平台。我不确定你是否可以直接把它包含到你的源代码中。
如果你在算法的这一部分不需要特别高的性能,一个更安全的做法是把它导出为字符串,然后再使用 strold
。