# Cast expression to rational number

Hello,

I am trying to perform the ceil() function on the result of a square root operation. My code is as follows:

x = 10
x = x.sqrt()
x = x.ceil()


However, I get the following error:

AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'ceil'


I have tried searching the the documentation, but I can't seem to find a straight forward way to "flatten" this expression to a rational number. How can I go about this?

Thanks,

edit retag close merge delete

Sort by » oldest newest most voted

Note that if you are taking the square root of an integer, the fastest might be the method sqrtrem that returns the floor of the square root and the remainder:

sage: x = 10
sage: s,r = x.sqrtrem()
sage: print s
3
sage: print r
1
sage: x == s^2 + r
True

more

1

Then you could get the ceiling as follows.

def sqrtceil(x):
"""
Return the ceiling of the square root of this integer
""""
s, r = x.sqrtrem()
if r:   # meaning if r nonzero, then sqrtceil = sqrtfloor + 1
return s + 1
else:  # meaning r is zero, ie x is a square, so sqrtfloor = sqrtceil
return s

1

Or condensed ;-)

def sqrtceil(x):
s, r = x.sqrtrem()
return s + bool(r)


When you take the square root of an integer number that is not a square, you get an object in Sage's "Symbolic Ring", where the ceil method is not available.

You could start with a floating-point 10 rather than an integer 10:

sage: x = RDF(10)
sage: x
10.0
sage: x.parent()
Real Double Field
sage: x = x.sqrt()
sage: x
3.1622776601683795
sage: x.parent()
Real Double Field
sage: x = x.ceil()
sage: x
4
sage: x.parent()
Integer Ring


Compare with your original computations:

sage: x = 10
sage: x
10
sage: x.parent()
Integer Ring
sage: x = x.sqrt()
sage: x
sqrt(10)
sage: x.parent()
Symbolic Ring
sage: x = x.ceil()
...
AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'ceil'

more

Interesting, but is there no way to force the Symbolic Ring to produce a flattened number?