Ask Your Question

unable to coerce <type 'sage.rings.real_mpfi.RealIntervalFieldElement'> to an integer

asked 2017-07-20 16:11:57 -0500

david gravatar image

I am very desperate. I just want to convert a real number to an integer. I have tried int(x), Integer(x), floor(x), ceil(x) but nothing seems to work.

edit retag flag offensive close merge delete


Both floor and ceil work for me. (Although this is no coercion, rather a forced push.)

sage: import random
sage: a = random.uniform( 10**5,10**9 )
sage: a
sage: floor(a)
sage: type( floor(a) )
<type 'sage.rings.integer.Integer'>
sage: floor(a).factor()
2 * 297542543
sage: ceil(a)
sage: ceil(a).factor()
5437 * 109451

As seen, the type of the floored a is a "sage integer", it has for instance the method factor.

Please provide code that fails for floor and/or ceil.

How to create an instance of that ...RealIntervalFieldElement type? (And this is no real number...)

dan_fulea gravatar imagedan_fulea ( 2017-07-21 04:04:34 -0500 )edit

3 answers

Sort by ยป oldest newest most voted

answered 2017-07-21 09:48:47 -0500

tmonteil gravatar image

If you want a more precise help, you need to provide your code (e.g. what is the precision of the number you are considering).

RealIntervalField elements are pairs of floating-point numbers representing an interval where the actual value is supposed to live. Such a representation is used to do numerical computations wile guaranteeing the error.

Since ZZ is an exact ring, it is not safe to transform such an interval into an integer, unless the two endpoints are equal and correspond to an integer (which could be implemented by the way).

The dirty way is to first transform your real interval element into a floating-point number, and then into an integer, for example:

sage: a = RIF(4)
sage: ZZ(RR(a))

Note however, the map from RIF to RR just takes the middle of the two endpoints:

sage: a = RIF(0,1)
sage: a
sage: a.endpoints()
(0.000000000000000, 1.00000000000000)
sage: RR(a)

Hence it can be dangerous:

sage: a = RIF(0,10)
sage: ZZ(RR(a))

sage: a = RIF(pi)
sage: b = RIF(3+pi)
sage: c = b-a
sage: c.endpoints()
(2.99999999999999, 3.00000000000001)
sage: in ZZ
sage: ZZ(RR(c))

(you could hence imagine situations where the center is an integer by chance while the represented number is not an integer, just close to one).

The only safe way to convert from RIF to ZZ is to first check that the endpoints are equal and in this case return it as an integer if it is an integer, something like:

sage: def intify(r):
....:     if r.is_exact():
....:         c =
....:         if c in ZZ:
....:             return ZZ(c)
....:         else:
....:             raise ValueError('The interval is exact but not an integer.')
....:     else:
....:         raise ValueError('The interval is not exact.')
sage: intify(RIF(2))
sage: intify(RIF(sqrt(2))*RIF(sqrt(2)))
ValueError: The interval is not exact.
sage: intify(RIF(0.5))
ValueError: The interval is exact but not an integer.
sage: intify(RIF(0,1))
ValueError: The interval is not exact.
edit flag offensive delete link more


Please note that we get errors for ZZ( RR( a ) ) when a "has a fractional part":

sage: a = RIF(4)
sage: ZZ( RR( a ) )
sage: try:    a = ZZ( RR( RIF( pi ) ) )
....: except TypeError:    print "TypeError!"


sage: try:    print ZZ( RR( RIF( 0, 9 ) ) )
....: except TypeError:    print "TypeError!"
sage: try:    print ZZ( RR( RIF( 0, 10 ) ) )
....: except TypeError:    print "TypeError!"
dan_fulea gravatar imagedan_fulea ( 2017-07-21 11:30:36 -0500 )edit

answered 2017-07-21 09:53:02 -0500

updated 2017-07-21 10:11:17 -0500

A real interval field element is a pair of real numbers (lower and upper)

sage: a = RIF(pi)
sage: a.lower()
sage: a.upper()
sage: b = RIF(3.24, 5.4)
sage: b.lower()
sage: b.upper()

You can see above that the interval is not necessarily small! And you can check that applying floor not necessarily leads to a unique possibility

sage: b.floor()
sage: b.floor().lower()
sage: b.floor().upper()

If you want to go from a real interval field to an integer there are the following methods

sage: a.unique_floor()
sage: a.unique_ceil()
sage: c = RIF(2.9, 3.1)
sage: c.unique_integer()

These methods might give errors when not appropriate

sage: a.unique_integer()
Traceback (most recent call last):
ValueError: interval contains no integer
sage: b.unique_floor()
Traceback (most recent call last):
ValueError: interval does not have a unique floor
edit flag offensive delete link more

answered 2017-07-21 05:09:02 -0500

dan_fulea gravatar image

updated 2017-07-21 05:10:46 -0500

I think, the problem occurs as in the following case:

sage: a = RIF( pi^3 )
sage: a
sage: floor(a), type(floor(a))
(31, <type 'sage.rings.real_mpfi.RealIntervalFieldElement'>)
sage: ceil(a), type(ceil(a))
(32, <type 'sage.rings.real_mpfi.RealIntervalFieldElement'>)

and the two methods work, but still do not leave the encapsulation, so no real number is provided. If this is the problem, then note that the "interval instance" a has a lower and an upper method, which leave the class, offer real numbers, where we can apply as desired floor and ceil... For instance:

sage: a = RIF( pi^3 )
sage: a

sage: a.lower(), type( a.lower() )
(31.0062766802998, <type 'sage.rings.real_mpfr.RealNumber'>)
sage: floor( a.lower() ), type( floor( a.lower() ) )
(31, <type 'sage.rings.integer.Integer'>)
sage: floor( a.lower() ) . is_prime()

sage: a.upper(), type( a.upper() )
(31.0062766802999, <type 'sage.rings.real_mpfr.RealNumber'>)
sage: ceil( a.upper() ), type( ceil( a.upper() ) )
(32, <type 'sage.rings.integer.Integer'>)
sage: ceil( a.upper() ) . is_prime_power()
edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2017-07-20 16:11:57 -0500

Seen: 55 times

Last updated: Jul 21