I'll throw my two cents in here.
First, the solution proposed in the other answers saying to use an external typedef is not just a workaround, that is the way the Cython docs say things like this should be done.
See the relevant section.
Quote: "If the header file uses typedef names such as word
to refer to platform-dependent flavours of numeric types, you will need a corresponding ctypedef statement, but you don’t need to match the type exactly, just use something of the right general kind (int, float, etc). For example ctypedef int word
will work okay whatever the actual size of a word
is (provided the header file defines it correctly). Conversion to and from Python types, if any, will also be used for this new type."
Also, it isn't necessary to actually create a header file with a typedef for a type you've already included somewhere else along the way.
Just do this
cdef extern from *:
ctypedef int int128 "__int128_t"
Or, if you feel like keeping the name the same in Cython as it is in C,
cdef extern from *:
ctypedef int __int128_t
Here's a test to demonstrate that this is working.
If the 128 bit arithmetic is working, a > 1
, and a is representable as a 64 bit integer, the first function will print the same number back again.
If it is not, integer overflow should cause it to print 0.
The second function shows what happens if 64 bit arithmetic is used.
Cython file
# 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
In Python, after both functions have been imported, myfunc(12321)
prints the correct value while myfunc_bad(12321)
prints 0.