# HG changeset patch
# User Jason Grout <jason-sage@creativetrax.com>
# Date 1208042128 18000
# Node ID ff925244bf571de7933f35e375f24c15439a2524
# Parent  f18d3a3a19d2957354277a18a94b4d7c26bb2f83
[mq]: trac-2898-coerce-to-Int.patch

diff -r f18d3a3a19d2 -r ff925244bf57 sage/rings/integer.pyx
--- a/sage/rings/integer.pyx	Wed Apr 09 03:45:43 2008 -0500
+++ b/sage/rings/integer.pyx	Sat Apr 12 18:15:28 2008 -0500
@@ -326,6 +326,16 @@
             sage: k = GF(2)
             sage: ZZ( (k(0),k(1)), 2)
             2
+            sage: ZZ(float(2.0))
+            2
+            sage: ZZ(float(1.0/0.0))
+            Traceback (most recent call last):
+            ...
+            OverflowError: cannot convert float infinity to long
+            sage: ZZ(float(0.0/0.0))
+            Traceback (most recent call last):
+            ...
+            TypeError: Cannot convert non-integral float to integer
         """
 
         # TODO: All the code below should somehow be in an external
@@ -359,6 +369,13 @@
 
             elif PyLong_CheckExact(x):
                 mpz_set_pylong(self.value, x)
+
+            elif PyFloat_CheckExact(x):
+                n = long(x)
+                if n == x:
+                    mpz_set_pylong(self.value, n)
+                else:
+                    raise TypeError, "Cannot convert non-integral float to integer"
 
             elif PY_TYPE_CHECK(x, pari_gen):
                 
diff -r f18d3a3a19d2 -r ff925244bf57 sage/rings/real_double.pyx
--- a/sage/rings/real_double.pyx	Wed Apr 09 03:45:43 2008 -0500
+++ b/sage/rings/real_double.pyx	Sat Apr 12 18:15:28 2008 -0500
@@ -460,6 +460,33 @@
         """
         return complex(self._value,0)
 
+    def _integer_(self):
+        """
+        If this floating-point number is actually an integer, return
+        that integer.  Otherwise, raise an exception.
+
+        EXAMPLES:
+            sage: ZZ(RDF(237.0))
+            237
+            sage: ZZ(RDF(0.0/0.0))
+            Traceback (most recent call last):
+            ...
+            TypeError: Cannot convert non-integral float to integer
+            sage: ZZ(RDF(1.0/0.0))
+            Traceback (most recent call last):
+            ...
+            OverflowError: cannot convert float infinity to long
+            sage: ZZ(RDF(-123456789.0))
+            -123456789
+            sage: ZZ(RDF((2.0))^290)
+            1989292945639146568621528992587283360401824603189390869761855907572637988050133502132224
+            sage: ZZ(RDF(-2345.67))
+            Traceback (most recent call last):
+            ...
+            TypeError: Cannot convert non-integral float to integer
+        """
+        return Integer(self._value)
+
     def parent(self):
         """
         Return the real double field, which is the parent of self.
@@ -577,9 +604,17 @@
             sage: a = r.integer_part(); a
             -1
             sage: type(a)
-            <type 'sage.rings.integer.Integer'>           
+            <type 'sage.rings.integer.Integer'>
+            sage: r = RDF(0.0/0.0)
+            sage: a = r.integer_part()
+            Traceback (most recent call last):
+            ...
+            TypeError: Attempt to get integer part of NaN
         """
-        return sage.rings.integer.Integer(int(self._value))
+        if gsl_isnan(self._value):
+            raise TypeError, "Attempt to get integer part of NaN"
+        else:
+            return Integer(int(self._value))
 
 
     ########################
@@ -794,11 +829,11 @@
         rounds down if fractional part is lesser than .5.
         EXAMPLES:
             sage: RDF(0.49).round()
-            0.0
-            sage: RDF(0.51).round()
-            1.0
+            0
+            sage: a=RDF(0.51).round(); a
+            1
         """
-        return RealDoubleElement(round(self._value))
+        return Integer(round(self._value))
 
     def floor(self):
         """
@@ -812,7 +847,7 @@
             sage: RDF(-5/2).floor()
             -3
         """
-        return sage.rings.integer.Integer(int(math.floor(self._value)))
+        return Integer(math.floor(self._value))
 
     def ceil(self):
         """
@@ -829,7 +864,7 @@
             sage: RDF(-5/2).ceil()
             -2
         """
-        return sage.rings.integer.Integer(int(math.ceil(self._value)))
+        return Integer(math.ceil(self._value))
 
     ceiling = ceil
 
@@ -839,13 +874,13 @@
 
         EXAMPLES:
             sage: RDF(2.99).trunc()
-            2.0
+            2
             sage: RDF(-2.00).trunc()
-            -2.0
+            -2
             sage: RDF(0.00).trunc()
-            0.0
+            0
         """
-        return RealDoubleElement(int(self._value))
+        return Integer(int(self._value))
 
     def frac(self):
         """
