Skip to content

Commit 59f64c1

Browse files
committed
fix: use long long on Windows
1 parent c0af7d4 commit 59f64c1

2 files changed

Lines changed: 38 additions & 9 deletions

File tree

src/flint/_flint.pxd

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
1-
# fixme!
2-
DEF FLINT_BITS = 64
1+
# _flint.pxd
2+
#
3+
# Define the contents of the Python, GMP, Flint and Arb headers.
34

45
cdef extern from "Python.h":
56
ctypedef void PyObject
67
ctypedef void PyTypeObject
78
ctypedef long Py_ssize_t
89
int PyObject_TypeCheck(object, PyTypeObject*)
910
int PyInt_Check(PyObject *o)
10-
PyObject* PyInt_FromLong(long ival)
1111
int PyLong_Check(PyObject *o)
1212
long PyInt_AS_LONG(PyObject *io)
1313
double PyFloat_AS_DOUBLE(PyObject *io)
1414
Py_ssize_t PyList_GET_SIZE(PyObject *list)
1515
long PyLong_AsLongAndOverflow(PyObject *pylong, int *overflow)
16+
long long PyLong_AsLongLongAndOverflow(PyObject *pylong, int *overflow)
1617

1718
DEF FMPZ_UNKNOWN = 0
1819
DEF FMPZ_REF = 1
1920
DEF FMPZ_TMP = 2
2021

22+
#
23+
# Note: ulong and slong are used throughout Flint/Arb. They are expected to be
24+
# 32 bit unsigned and signed integer types on a 32 bit system and 64 bit on a
25+
# 64 bit system. We denote them as unsigned long and long here which would be
26+
# incorrect on 64 bit Windows but the definition here does not matter because
27+
# their actual sizes will be determined by the values from gmp.h and
28+
# flint/flint.h. Their size in bits (32 or 64) is recorded in the FLINT_BITS
29+
# macro which is defined in flint/flint.h.
30+
#
31+
2132
cdef extern from "gmp.h":
2233
ctypedef unsigned long ulong
2334
ctypedef unsigned long mp_limb_t
@@ -27,18 +38,36 @@ cdef extern from "gmp.h":
2738
ctypedef mp_limb_t* mp_srcptr
2839
ctypedef unsigned long mp_bitcnt_t
2940

30-
ctypedef long fmpz_struct
31-
ctypedef long slong
32-
ctypedef ulong flint_bitcnt_t
41+
cdef extern from "flint/fmpz.h":
42+
ctypedef long slong
43+
ctypedef ulong flint_bitcnt_t
44+
45+
ctypedef slong fmpz_struct
3346

3447
cdef extern from "flint/flint.h":
48+
const int FLINT_BITS
3549
ctypedef void * flint_rand_t
3650
void flint_randinit(flint_rand_t state)
3751
void flint_randclear(flint_rand_t state)
3852
void flint_set_num_threads(long)
3953
long flint_get_num_threads()
4054
void flint_cleanup()
4155

56+
cdef extern from *:
57+
"""
58+
/* FLINT_BITS is not known until C compile time. We need to check if long
59+
* or long long matches FLINT_BITS to know which CPython function to call.
60+
*/
61+
#if FLINT_BITS == 32 && LONG_MAX == 2147483647
62+
#define pylong_as_slong PyLong_AsLongAndOverflow
63+
#elif FLINT_BITS == 64 && LLONG_MAX == 9223372036854775807
64+
#define pylong_as_slong PyLong_AsLongLongAndOverflow
65+
#else
66+
#error FLINT_BITS does not match width of long or long long.
67+
#endif
68+
"""
69+
slong pylong_as_slong(PyObject *pylong, int *overflow)
70+
4271
cdef extern from "flint/nmod_vec.h":
4372
ctypedef struct nmod_t:
4473
mp_limb_t n

src/flint/fmpz.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cdef inline int fmpz_set_pylong(fmpz_t x, obj):
22
cdef int overflow
3-
cdef long longval
4-
longval = PyLong_AsLongAndOverflow(<PyObject*>obj, &overflow)
3+
cdef slong longval
4+
longval = pylong_as_slong(<PyObject*>obj, &overflow)
55
if overflow:
66
s = "%x" % obj
77
fmpz_set_str(x, chars_from_str(s), 16)
@@ -28,7 +28,7 @@ cdef fmpz_get_intlong(fmpz_t x):
2828
libc.stdlib.free(s)
2929
return v
3030
else:
31-
return <long>x[0]
31+
return <slong>x[0]
3232

3333
cdef int fmpz_set_any_ref(fmpz_t x, obj):
3434
if typecheck(obj, fmpz):

0 commit comments

Comments
 (0)