Chi*_*nke 9 c gcc int128 cython long-integer
在我的64位计算机上,long long类型有64位.
print(sizeof(long long))
# prints 8
Run Code Online (Sandbox Code Playgroud)
我需要使用128位整数,幸运的是GCC支持这些.我怎样才能在Cython中使用它们?
以下不起作用.编译foo.pyx只包含
cdef __int128_t x = 0
Run Code Online (Sandbox Code Playgroud)
产量
$ cython foo.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cdef __int128_t x = 0
^
------------------------------------------------------------
foo.pyx:2:5: '__int128_t' is not a type identifier
Run Code Online (Sandbox Code Playgroud)
编辑:这不再是一种解决方法,这是正确的方法.另请参阅@ IanH的答案.
现在,你遇到的问题是cython无法识别你的类型gcc.所以我们可以尝试欺骗cython.
档案helloworld.pyx:
cdef extern from "header_int128.h":
# this is WRONG, as this would be a int64. it is here
# just to let cython pass the first step, which is generating
# the .c file.
ctypedef unsigned long long int128
print "hello world"
cpdef int foo():
cdef int128 foo = 4
return 32
Run Code Online (Sandbox Code Playgroud)
档案header_int128.h:
typedef __int128_t int128;
Run Code Online (Sandbox Code Playgroud)
档案setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("helloworld.pyx"))
Run Code Online (Sandbox Code Playgroud)
现在,在我的机器上,当我运行时python setup.py build_ext --inplace,第一步通过,helloworld.c生成文件,然后gcc编译也通过.
现在,如果您打开文件helloworld.c,则可以检查您的变量foo是否实际声明为int128.
使用此变通方法时要非常小心.特别是,如果你int128为一个int64例子分配一个,那么cython就不会需要在C代码中使用强制转换,因为在该过程的那一步它实际上并没有区分它们.
我会把我的两分钱扔在这里。
首先,其他答案中提出的解决方案说使用外部 typedef 不仅仅是一种解决方法,这也是 Cython 文档所说的应该完成这样的事情的方式。请参阅相关部分。引用:“如果头文件使用 typedef 名称word来引用依赖于平台的数字类型风格,您将需要一个相应的 ctypedef 语句,但您不需要完全匹配类型,只需使用正确的通用内容kind (int, float, etc)。例如,ctypedef int word无论 a 的实际大小如何,都可以正常工作word(前提是头文件正确定义了它)。与 Python 类型之间的转换(如果有)也将用于这种新类型。 ”
此外,没有必要为您已经在其他地方包含的类型实际创建一个带有 typedef 的头文件。就这样做
cdef extern from *:
ctypedef int int128 "__int128_t"
Run Code Online (Sandbox Code Playgroud)
或者,如果您想让 Cython 中的名称与 C 中的名称相同,
cdef extern from *:
ctypedef int __int128_t
Run Code Online (Sandbox Code Playgroud)
这是一个测试来证明这是有效的。如果 128 位算术有效,a > 1并且 a 可表示为 64 位整数,则第一个函数将再次打印相同的数字。如果不是,整数溢出应该导致它打印 0。第二个函数显示如果使用 64 位算法会发生什么。
Cython 文件
# cython: cdivision = True
cdef extern from *:
ctypedef int int128 "__int128_t"
def myfunc(long long a):
cdef int128 i = a
# set c to be the largest positive integer possible for a signed 64 bit integer
cdef long long c = 0x7fffffffffffffff
i *= c
cdef long long b = i / c
print b
def myfunc_bad(long long a):
cdef long long i = a
# set c to be the largest positive integer possible for a signed 64 bit integer
cdef long long c = 0x7fffffffffffffff
i *= c
cdef long long b = i / c
print b
Run Code Online (Sandbox Code Playgroud)
在 Python 中,导入两个函数后,myfunc(12321)打印正确的值,同时myfunc_bad(12321)打印 0。
| 归档时间: |
|
| 查看次数: |
1467 次 |
| 最近记录: |