Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/flint/flintlib/functions/fmpz.pxd
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flint.flintlib.types.flint cimport flint_bitcnt_t, flint_rand_t, fmpz_struct, fmpz_t, nmod_t, nn_ptr, nn_srcptr, slong, ulong
from flint.flintlib.types.flint cimport flint_bitcnt_t, flint_rand_t, fmpz_struct, fmpz_t, nmod_t, nn_ptr, nn_srcptr, slong, ulong, mpz_ptr, mpz_t
from flint.flintlib.types.fmpz cimport fmpz_factor_t, fmpz_preinvn_t

# unknown type FILE
Expand All @@ -17,6 +17,11 @@ from flint.flintlib.types.fmpz cimport fmpz_factor_t, fmpz_preinvn_t
# .. macro:: COEFF_IS_MPZ(f)
# .. macro:: MPZ_MIN_ALLOC

cdef extern from "gmp.h":
void mpz_import(mpz_t val, size_t count, int order, size_t size, int endian, size_t nails, const void * op)
void * mpz_export (void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mpz_t op)


cdef extern from "flint/fmpz.h":
# fmpz_struct PTR_TO_COEFF(mpz_ptr ptr)
# mpz_ptr COEFF_TO_PTR(fmpz_struct f)
Expand All @@ -25,7 +30,7 @@ cdef extern from "flint/fmpz.h":
void _fmpz_cleanup_mpz_content()
void _fmpz_cleanup()
# mpz_ptr _fmpz_promote(fmpz_t f)
# mpz_ptr _fmpz_promote_val(fmpz_t f)
mpz_ptr _fmpz_promote_val(fmpz_t f)
void _fmpz_demote(fmpz_t f)
void _fmpz_demote_val(fmpz_t f)
int _fmpz_is_canonical(const fmpz_t f)
Expand Down Expand Up @@ -84,7 +89,7 @@ cdef extern from "flint/fmpz.h":
# int fmpz_fprint(FILE * fs, const fmpz_t x)
int fmpz_print(const fmpz_t x)
# size_t fmpz_out_raw(FILE * fout, const fmpz_t x )
# size_t fmpz_sizeinbase(const fmpz_t f, int b)
size_t fmpz_sizeinbase(const fmpz_t f, int b)
flint_bitcnt_t fmpz_bits(const fmpz_t f)
slong fmpz_size(const fmpz_t f)
int fmpz_sgn(const fmpz_t f)
Expand Down
35 changes: 35 additions & 0 deletions src/flint/flintlib/types/flint.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@
#
# Define fundamental types and constants

from libc.stdint cimport int8_t, uint8_t, int64_t

cdef extern from "Python.h":
ctypedef void PyObject

ctypedef unsigned long long Py_uintptr_t

cdef struct PyLongLayout:
uint8_t bits_per_digit
uint8_t digit_size
int8_t digits_order
int8_t digit_endianness

const PyLongLayout * PyLong_GetNativeLayout()

cdef struct PyLongExport:
int64_t value
uint8_t negative
Py_ssize_t ndigits
const void *digits
Py_uintptr_t _reserved

int PyLong_Export(object, PyLongExport *)
void PyLong_FreeExport(PyLongExport *)

ctypedef struct PyLongWriter:
pass

PyLongWriter * PyLongWriter_Create(int negative, Py_ssize_t ndigits, void **digits)
object PyLongWriter_Finish(PyLongWriter *writer)
void PyLongWriter_Discard(PyLongWriter *writer)


cdef enum:
FMPZ_UNKNOWN = 0
FMPZ_REF = 1
Expand All @@ -30,6 +60,11 @@ cdef extern from "gmp.h":
ctypedef mp_limb_t* mp_srcptr
ctypedef unsigned long mp_bitcnt_t

ctypedef struct __mpz_struct:
pass
ctypedef __mpz_struct mpz_t[1]
ctypedef __mpz_struct * mpz_ptr

cdef extern from "flint/fmpz.h":
ctypedef long slong
ctypedef ulong flint_bitcnt_t
Expand Down
45 changes: 34 additions & 11 deletions src/flint/types/fmpz.pxd
Original file line number Diff line number Diff line change
@@ -1,22 +1,45 @@
from cpython.long cimport PyLong_Check
from flint.flint_base.flint_base cimport flint_scalar
from flint.utils.conversion cimport chars_from_str
from flint.flintlib.types.flint cimport slong, pylong_as_slong
from flint.flintlib.types.flint cimport PyObject
from flint.flintlib.functions.fmpz cimport fmpz_t, fmpz_set_str, fmpz_set_si
from flint.flintlib.types.flint cimport PyObject, PyLongLayout, PyLong_GetNativeLayout, PyLongExport, PyLong_Export, PyLong_FreeExport
from flint.flintlib.functions.fmpz cimport fmpz_t, fmpz_set_str, fmpz_set_si, _fmpz_promote_val, _fmpz_demote_val, mpz_import, fmpz_neg, fmpz_ui_pow_ui, fmpz_init, fmpz_sub, fmpz_clear

cdef extern from "<limits.h>":
const long LONG_MAX
const long LONG_MIN

cdef int fmpz_set_any_ref(fmpz_t x, obj)
cdef fmpz_get_intlong(fmpz_t x)

cdef inline int fmpz_set_pylong(fmpz_t x, obj):
cdef int overflow
cdef slong longval
longval = pylong_as_slong(<PyObject*>obj, &overflow)
if overflow:
s = "%x" % obj
fmpz_set_str(x, chars_from_str(s), 16)
cdef const PyLongLayout * layout
cdef PyLongExport long_export
cdef fmpz_t tmp

layout = PyLong_GetNativeLayout()

PyLong_Export(obj, &long_export)
if long_export.digits:
z = _fmpz_promote_val(x)
mpz_import(z, long_export.ndigits, layout[0].digits_order,
layout[0].digit_size, layout[0].digit_endianness,
layout[0].digit_size*8 - layout[0].bits_per_digit,
long_export.digits)
_fmpz_demote_val(x)
if long_export.negative:
fmpz_neg(x, x)
PyLong_FreeExport(&long_export)
else:
fmpz_set_si(x, longval)
if LONG_MIN <= long_export.value <= LONG_MAX:
fmpz_set_si(x, long_export.value)
else:
z = _fmpz_promote_val(x)
mpz_import(z, 1, -1, 8, 0, 0, &long_export.value);
_fmpz_demote_val(x)
if long_export.value < 0:
fmpz_init(tmp)
fmpz_ui_pow_ui(tmp, 2, 64)
fmpz_sub(x, x, tmp)
fmpz_clear(tmp)

cdef inline int fmpz_set_python(fmpz_t x, obj):
if PyLong_Check(obj):
Expand Down
30 changes: 21 additions & 9 deletions src/flint/types/fmpz.pyx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from cpython.long cimport PyLong_FromLong
from flint.flint_base.flint_base cimport flint_scalar
from flint.utils.typecheck cimport typecheck
from flint.utils.conversion cimport chars_from_str
from flint.utils.conversion cimport str_from_chars, _str_trunc
cimport libc.stdlib

from flint.flintlib.types.flint cimport FMPZ_REF, FMPZ_TMP, FMPZ_UNKNOWN, COEFF_IS_MPZ
from flint.flintlib.types.flint cimport FMPZ_REF, FMPZ_TMP, FMPZ_UNKNOWN, COEFF_IS_MPZ, PyLongLayout, PyLong_GetNativeLayout, PyLongWriter_Create, PyLongWriter_Finish, PyLongWriter
from flint.flintlib.functions.flint cimport flint_free
from flint.flintlib.functions.fmpz cimport *
from flint.flintlib.types.fmpz cimport fmpz_factor_expand
Expand All @@ -17,16 +18,27 @@ from flint.utils.flint_exceptions import DomainError

cdef fmpz_get_intlong(fmpz_t x):
"""
Convert fmpz_t to a Python int or long.
Convert fmpz_t to a Python int.
"""
cdef char * s
if COEFF_IS_MPZ(x[0]):
s = fmpz_get_str(NULL, 16, x)
v = int(str_from_chars(s), 16)
flint_free(s)
return v
cdef const PyLongLayout *layout
cdef void *digits
cdef PyLongWriter *writer
cdef size_t size

if fmpz_fits_si(x):
return PyLong_FromLong(fmpz_get_si(x))
else:
return <slong>x[0]
layout = PyLong_GetNativeLayout()
size = (fmpz_sizeinbase(x, 2) +
layout[0].bits_per_digit - 1)//layout[0].bits_per_digit
writer = PyLongWriter_Create(fmpz_sgn(x) < 0, size, &digits)
if writer:
z = _fmpz_promote_val(x)
mpz_export(digits, NULL, layout[0].digits_order,
layout[0].digit_size, layout[0].digit_endianness,
layout[0].digit_size*8 - layout[0].bits_per_digit, z);
_fmpz_demote_val(x)
return PyLongWriter_Finish(writer);

cdef int fmpz_set_any_ref(fmpz_t x, obj):
if typecheck(obj, fmpz):
Expand Down
Loading