Skip to content

Commit 491f133

Browse files
authored
Merge pull request #391 from rikardn/optrational
Faster rational creation
2 parents c389254 + 9d36b49 commit 491f133

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

symengine/lib/symengine.pxd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ cdef extern from "<symengine/integer.h>" namespace "SymEngine":
379379
Integer(integer_class i) nogil
380380
int compare(const Basic &o) nogil
381381
integer_class as_integer_class() nogil
382+
RCP[Number] divint(const Integer &other) nogil
382383
cdef long mp_get_si(integer_class &i) nogil
383384
cdef double mp_get_d(integer_class &i) nogil
384385
cdef RCP[const Integer] integer(int i) nogil
@@ -390,6 +391,8 @@ cdef extern from "<symengine/integer.h>" namespace "SymEngine":
390391
cdef extern from "<symengine/rational.h>" namespace "SymEngine":
391392
cdef cppclass Rational(Number):
392393
rational_class as_rational_class() nogil
394+
@staticmethod
395+
RCP[const Number] from_two_ints(const long n, const long d) nogil
393396
cdef double mp_get_d(rational_class &i) nogil
394397
cdef RCP[const Number] from_mpq "SymEngine::Rational::from_mpq"(rational_class r) nogil
395398
cdef void get_num_den(const Rational &rat, const Ptr[RCP[Integer]] &num,

symengine/lib/symengine_wrapper.pyx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1664,7 +1664,25 @@ cdef class Number(Expr):
16641664
class Rational(Number):
16651665

16661666
def __new__(cls, p, q):
1667-
return Integer(p)/q
1667+
p = int(p)
1668+
q = int(q)
1669+
cdef int p_
1670+
cdef int q_
1671+
cdef symengine.integer_class p__
1672+
cdef symengine.integer_class q__
1673+
cdef string tmp
1674+
try:
1675+
# Try to convert p and q to int
1676+
p_ = p
1677+
q_ = q
1678+
return c2py(<rcp_const_basic>symengine.Rational.from_two_ints(p_, q_));
1679+
except OverflowError:
1680+
# Too big, need to use mpz
1681+
tmp = str(p).encode("utf-8")
1682+
p__ = symengine.integer_class(tmp)
1683+
tmp = str(q).encode("utf-8")
1684+
q__ = symengine.integer_class(tmp)
1685+
return c2py(<rcp_const_basic>symengine.Integer(p__).divint(symengine.Integer(q__)))
16681686

16691687
@property
16701688
def is_Rational(self):

0 commit comments

Comments
 (0)