@@ -2293,6 +2293,61 @@ cdef class Expression(CommutativeRingElement):
22932293 """
22942294 return is_a_relational(self ._gobj)
22952295
2296+ def is_exact (self ):
2297+ """
2298+ Return True if this expression only contains exact numerical coefficients.
2299+
2300+ EXAMPLES::
2301+
2302+ sage: x, y = var('x, y')
2303+ sage: (x+y-1).is_exact()
2304+ True
2305+ sage: (x+y-1.9).is_exact()
2306+ False
2307+ sage: x.is_exact()
2308+ True
2309+ sage: pi.is_exact()
2310+ True
2311+ sage: (sqrt(x-y) - 2*x + 1).is_exact()
2312+ True
2313+ sage: ((x-y)^0.5 - 2*x + 1).is_exact()
2314+ False
2315+
2316+ TESTS::
2317+
2318+ sage: (sin(x*cos(2*x*pi)) - 10*y^3 - 1/(x+4)).is_exact()
2319+ True
2320+ sage: (sin(x*cos(2.0*x*pi)) - 10*y^3 - 1/(x+4)).is_exact()
2321+ False
2322+ sage: SR(42).is_exact()
2323+ True
2324+ sage: SR(42.01).is_exact()
2325+ False
2326+ sage: SR(I).is_exact()
2327+ True
2328+ sage: (x-I).is_exact()
2329+ True
2330+ sage: (x-CC(0,1)).is_exact()
2331+ False
2332+ """
2333+ # generator over all numerical elements in the subexpression tree of expr
2334+ def numelems_gen (expr ):
2335+ if expr.is_numeric():
2336+ yield expr
2337+ elif expr.operator() is not None :
2338+ for op in expr.operands():
2339+ if op.is_numeric():
2340+ yield op
2341+ else :
2342+ for opp in numelems_gen(op):
2343+ yield opp
2344+ # stop at the first inexact number in the subexpression tree of self,
2345+ # and if there is no such element, then self is exact
2346+ for nelem in numelems_gen(self ):
2347+ if not nelem.pyobject().base_ring().is_exact():
2348+ return False
2349+ return True
2350+
22962351 cpdef bint is_infinity(self ):
22972352 """
22982353 Return True if self is an infinite expression.
0 commit comments