On my 64 bit computer the long long
type has 64 bits.
print(sizeof(long long))
# prints 8
I need to use 128 bit integers and luckily GCC supports these. How can I use these within Cython?
The following doesn't work. Compiling foo.pyx
containing just
cdef __int128_t x = 0
yields
$ cython foo.pyx
Error compiling Cython file:
------------------------------------------------------------
...
cdef __int128_t x = 0
^
------------------------------------------------------------
foo.pyx:2:5: '__int128_t' is not a type identifier
EDIT: this is NOT a workaround anymore, this is the right way to do it. Refer also to @IanH's answer.
Now, the problem you have is that cython
does not recognize your type, while gcc
does. So we can try to trick cython
.
File 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
File header_int128.h
:
typedef __int128_t int128;
File setup.py
:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("helloworld.pyx"))
Now, on my machine, when I run python setup.py build_ext --inplace
, the first step passes, and the file helloworld.c
is generated, and then the gcc
compilation passes as well.
Now if you open the file helloworld.c
, you can check that your variable foo
is actually declared as an int128
.
Be very careful with using this workaround. In particular, it can happen that cython will not require a cast in the C code if you assign an int128
to a int64
for example, because at that step of the process it actually does not distinguish between them.