1 | initial version |
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))
4
Note however, the map from RIF
to RR
just takes the middle of the two endpoints:
sage: a = RIF(0,1)
sage: a
1.?
sage: a.endpoints()
(0.000000000000000, 1.00000000000000)
sage: RR(a)
0.500000000000000
Hence it can be dangerous:
sage: a = RIF(0,10)
sage: ZZ(RR(a))
5
sage: a = RIF(pi)
sage: b = RIF(3+pi)
sage: c = b-a
sage: c.endpoints()
(2.99999999999999, 3.00000000000001)
sage: c.center()
3.00000000000000
sage: c.center() in ZZ
True
sage: ZZ(RR(c))
3
(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 = r.center()
....: 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))
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.