Abh*_*nav 6 python numpy cython long-double
我正在尝试使用np.longdouble我的Python代码中的dtype,并且我正在尝试使用NumPy来操作从使用Cython编译的C模块获得的长双精度.
假设我这样做:
import numpy as np
print np.finfo(np.longdouble)
Machine parameters for float128
---------------------------------------------------------------------
precision= 18 resolution= 1e-18
machep= -63 eps= 1.08420217249e-19
negep = -64 epsneg= 5.42101086243e-20
minexp=-16382 tiny= 3.36210314311e-4932
maxexp= 16384 max= 1.18973149536e+4932
nexp = 15 min= -max
---------------------------------------------------------------------
a = np.longdouble(1e+346)
a
Out[4]: inf
b = np.longdouble(1e+347)
b
Out[6]: inf
c = a/b
/usr/lib/python2.7/site-packages/spyderlib/widgets/externalshell/start_ipython_kernel.py:1:
RuntimeWarning: invalid value encountered in longdouble_scalars
# -*- coding: utf-8 -*-
c
Out[8]: nan
a.dtype, b.dtype, c.dtype
Out[9]: (dtype('float128'), dtype('float128'), dtype('float128'))
Run Code Online (Sandbox Code Playgroud)
本质上,它与此问题中的相同问题相关联,并且我理解Python首先将其1e+346转换为浮点数,其重新定位将是inf.但是,有人可以建议一个解决方法吗?有没有办法创建未首先转换为浮点数的NumPy longdoubles?
我有一个可以输出长双打的C模块,我想在dtype的numpy数组中使用它np.longdouble.
即使解决方案涉及重新编译Python/NumPy,我也愿意尝试.
您可能需要考虑一些事项.
首先,这是一团糟.NumPy知道longdouble并且float128.不幸的是,这些名称具有误导性,底层实现是C long double,通常(但不一定总是)是80位浮点数.(实际上你可以通过查看"精度"看到它; 18位是大约60位,80位浮点数的尾数是64位.如果使用真正的128位浮点数,精度将是34位左右. )
可能没有任何直接的方法可以将long double作为参数传递给C函数,但是如果你传递指针,那么你可以避免这个问题.例如,您可以将数组数据作为uint8(通过使用myarray.view(dtype='uint8'))传递,并将指向缓冲区的指针转换为C程序中的long double*.至少Python与类型转换无关.(很可能你不需要拿它,view因为你毕竟只是导出一个指向数组缓冲区的指针.)
请注意,在编译Python和C程序时,这个技巧依赖于编译器具有相同类型的设置.除了精度差异之外,可能存在字节顺序差异(如果程序在同一台机器上运行,则很少)和对齐差异.我的Python似乎将longdouble项目对齐为16字节边界(即每个元素总共有6个字节的零),但C编译器可能使用10/12/16字节对齐.
据我所知,细节是特定于实现的.所以,这是可行的,但需要一些额外的照顾,可能存在可移植性问题.