Skip to content

Commit 4da6b11

Browse files
More efficient conversion of fmpz to float
1 parent 0a59f53 commit 4da6b11

File tree

2 files changed

+10
-1
lines changed

2 files changed

+10
-1
lines changed

src/flint/test/test_all.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ def test_fmpz():
207207
assert math.ceil(f) == 2
208208
assert type(math.ceil(f)) is flint.fmpz
209209

210+
# Test float conversion overflow
211+
assert raises(lambda: float(flint.fmpz(2**1024)), OverflowError)
212+
assert raises(lambda: float(flint.fmpz(-2**1024)), OverflowError)
213+
210214
assert flint.fmpz(2) != []
211215
assert +flint.fmpz(0) == 0
212216
assert +flint.fmpz(1) == 1

src/flint/types/fmpz.pyx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ from flint.utils.typecheck cimport typecheck
33
from flint.utils.conversion cimport chars_from_str
44
from flint.utils.conversion cimport str_from_chars, _str_trunc
55
cimport libc.stdlib
6+
import math
67

78
from flint.flintlib.types.flint cimport FMPZ_REF, FMPZ_TMP, FMPZ_UNKNOWN, COEFF_IS_MPZ
89
from flint.flintlib.functions.flint cimport flint_free
@@ -105,7 +106,11 @@ cdef class fmpz(flint_scalar):
105106
return fmpz_get_intlong(self.val)
106107

107108
def __float__(self):
108-
return float(fmpz_get_intlong(self.val))
109+
cdef slong exp
110+
# fmpz_get_d_2exp is always accurate
111+
# math.ldexp handles overflow checks
112+
cdef double d = fmpz_get_d_2exp(&exp, self.val)
113+
return math.ldexp(d, exp)
109114

110115
def __floor__(self):
111116
return self

0 commit comments

Comments
 (0)