From 9dfcbf20bd3566ae4444dc9056fd01b4599f2d19 Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Tue, 28 Jan 2025 15:22:14 +0100 Subject: [PATCH] gr: Improve conversions C.f. https://flintlib.org/doc/gr.html#assignment-and-conversions We can use more appropriate functions for conversions than roundtripping through a string --- src/flint/types/_gr.pxd | 20 ++++++++++++++++++++ src/flint/types/_gr.pyx | 22 +++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/flint/types/_gr.pxd b/src/flint/types/_gr.pxd index 5f948c27..e02738c5 100644 --- a/src/flint/types/_gr.pxd +++ b/src/flint/types/_gr.pxd @@ -86,6 +86,8 @@ from flint.flintlib.functions.gr_domains cimport ( ) from flint.flintlib.functions.gr cimport ( gr_heap_init, + gr_set_d, + gr_set_other, gr_set_str, gr_get_str, gr_set, @@ -214,6 +216,24 @@ cdef class gr_ctx(flint_ctx): py_val._init = True return py_val + @cython.final + cdef inline gr from_d(self, double d): + cdef gr py_val + py_val = self.new_gr() + err = gr_set_d(py_val.pval, d, self.ctx_t) + if err != GR_SUCCESS: + raise self._error(err, "Incorrect conversion from a double") + return py_val + + @cython.final + cdef inline gr from_other(self, gr x): + cdef gr py_val + py_val = self.new_gr() + err = gr_set_other(py_val.pval, x.pval, x.ctx.ctx_t, self.ctx_t) + if err != GR_SUCCESS: + raise self._error(err, "Incorrect conversion") + return py_val + @cython.final cdef inline gr from_str(self, s: str): cdef gr py_val diff --git a/src/flint/types/_gr.pyx b/src/flint/types/_gr.pyx index 059884d7..f8e98432 100644 --- a/src/flint/types/_gr.pyx +++ b/src/flint/types/_gr.pyx @@ -224,11 +224,23 @@ cdef class gr_ctx(flint_ctx): def __call__(self, arg) -> gr: """Create a new element of the domain. - >>> from flint.types._gr import gr_fmpz_ctx - >>> ctx = gr_fmpz_ctx - >>> ctx(2) - 2 - """ + >>> from flint.types._gr import gr_fmpz_ctx + >>> ctx = gr_fmpz_ctx + >>> ctx(2) + 2 + >>> ctx(18446744073709551615) + 18446744073709551615 + """ + if isinstance(arg, gr): + return self.from_other(arg) + if type(arg) is int: + try: + return self.from_si(arg) + except OverflowError: + pass + if type(arg) is float: + return self.from_d(arg) + # TODO: fmpz & fmpq ? try: return self.from_str(str(arg)) except AssertionError: