|
1 | 1 | from cpython.long cimport PyLong_Check
|
2 | 2 | from flint.flint_base.flint_base cimport flint_scalar
|
3 | 3 | from flint.utils.conversion cimport chars_from_str
|
4 |
| -from flint.flintlib.types.flint cimport slong, pylong_as_slong |
| 4 | +from flint.flintlib.types.flint cimport slong, ulong, pylong_as_slong |
5 | 5 | from flint.flintlib.types.flint cimport PyObject
|
6 |
| -from flint.flintlib.functions.fmpz cimport fmpz_t, fmpz_set_str, fmpz_set_si |
| 6 | +from flint.flintlib.functions.fmpz cimport fmpz_t, fmpz_set_si, fmpz_set_signed_ui_array |
| 7 | +import sys |
7 | 8 |
|
8 | 9 | cdef int fmpz_set_any_ref(fmpz_t x, obj)
|
9 | 10 | cdef fmpz_get_intlong(fmpz_t x)
|
10 | 11 |
|
| 12 | +cdef extern from "byteswap.h": |
| 13 | + """ |
| 14 | + #if FLINT_BITS == 32 |
| 15 | + #define bswap_ulong bswap_32 |
| 16 | + #elif FLINT_BITS == 64 |
| 17 | + #define bswap_ulong bswap_64 |
| 18 | + #else |
| 19 | + #error FLINT_BITS must be 32 or 64 |
| 20 | + #endif |
| 21 | + """ |
| 22 | + ulong bswap_ulong(ulong x) |
| 23 | + |
11 | 24 | cdef inline int fmpz_set_pylong(fmpz_t x, obj):
|
12 | 25 | cdef int overflow
|
13 | 26 | cdef slong longval
|
| 27 | + cdef slong size |
| 28 | + cdef bytes b |
| 29 | + cdef ulong *words |
| 30 | + |
14 | 31 | longval = pylong_as_slong(<PyObject*>obj, &overflow)
|
15 | 32 | if overflow:
|
16 |
| - s = "%x" % obj |
17 |
| - fmpz_set_str(x, chars_from_str(s), 16) |
| 33 | + # make sure the sign bit fits |
| 34 | + # we need sizeof(ulong) * size > obj.bit_length() |
| 35 | + size = obj.bit_length() // sizeof(ulong) + 1 |
| 36 | + b = obj.to_bytes(sizeof(ulong) * size, "little", signed=True) |
| 37 | + # b is a local Python object, we access the internal pointer |
| 38 | + words = <ulong*>(<char *>b) |
| 39 | + # sys must be imported by the caller |
| 40 | + if sys.byteorder == "big": |
| 41 | + for i in range(size): |
| 42 | + words[i] = bswap_ulong(words[i]) |
| 43 | + fmpz_set_signed_ui_array(x, words, size) |
18 | 44 | else:
|
19 | 45 | fmpz_set_si(x, longval)
|
20 | 46 |
|
|
0 commit comments