[Python-checkins] bpo-38629: implement __floor__ and __ceil__ for float type (GH-16985)

Victor Stinner webhook-mailer at python.org
Sun Dec 15 17:00:43 EST 2019


https://github.com/python/cpython/commit/cb8b946ac10386e6cab1376945f64f683b5b16d3
commit: cb8b946ac10386e6cab1376945f64f683b5b16d3
branch: master
author: Batuhan Taşkaya <47358913+isidentical at users.noreply.github.com>
committer: Victor Stinner <vstinner at python.org>
date: 2019-12-15T23:00:28+01:00
summary:

bpo-38629: implement __floor__ and __ceil__ for float type (GH-16985)

files:
A Misc/NEWS.d/next/Core and Builtins/2019-10-29-17-11-15.bpo-38629.3qinhF.rst
M Lib/test/test_float.py
M Objects/clinic/floatobject.c.h
M Objects/floatobject.c

diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index b656582538e87..9651281e24edb 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -312,6 +312,34 @@ def assertEqualAndEqualSign(self, a, b):
         # distinguishes -0.0 and 0.0.
         self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
 
+    def test_float_floor(self):
+        self.assertIsInstance(float(0.5).__floor__(), int)
+        self.assertEqual(float(0.5).__floor__(), 0)
+        self.assertEqual(float(1.0).__floor__(), 1)
+        self.assertEqual(float(1.5).__floor__(), 1)
+        self.assertEqual(float(-0.5).__floor__(), -1)
+        self.assertEqual(float(-1.0).__floor__(), -1)
+        self.assertEqual(float(-1.5).__floor__(), -2)
+        self.assertEqual(float(1.23e167).__floor__(), 1.23e167)
+        self.assertEqual(float(-1.23e167).__floor__(), -1.23e167)
+        self.assertRaises(ValueError, float("nan").__floor__)
+        self.assertRaises(OverflowError, float("inf").__floor__)
+        self.assertRaises(OverflowError, float("-inf").__floor__)
+
+    def test_float_ceil(self):
+        self.assertIsInstance(float(0.5).__ceil__(), int)
+        self.assertEqual(float(0.5).__ceil__(), 1)
+        self.assertEqual(float(1.0).__ceil__(), 1)
+        self.assertEqual(float(1.5).__ceil__(), 2)
+        self.assertEqual(float(-0.5).__ceil__(), 0)
+        self.assertEqual(float(-1.0).__ceil__(), -1)
+        self.assertEqual(float(-1.5).__ceil__(), -1)
+        self.assertEqual(float(1.23e167).__ceil__(), 1.23e167)
+        self.assertEqual(float(-1.23e167).__ceil__(), -1.23e167)
+        self.assertRaises(ValueError, float("nan").__ceil__)
+        self.assertRaises(OverflowError, float("inf").__ceil__)
+        self.assertRaises(OverflowError, float("-inf").__ceil__)
+
     @support.requires_IEEE_754
     def test_float_mod(self):
         # Check behaviour of % operator for IEEE 754 special cases.
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-10-29-17-11-15.bpo-38629.3qinhF.rst b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-17-11-15.bpo-38629.3qinhF.rst
new file mode 100644
index 0000000000000..dadafcd898af5
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-10-29-17-11-15.bpo-38629.3qinhF.rst	
@@ -0,0 +1 @@
+Added ``__floor__`` and ``__ceil__`` methods to float object. Patch by Batuhan Taşkaya.
diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h
index b684ba0ef27aa..b7554832b5a8a 100644
--- a/Objects/clinic/floatobject.c.h
+++ b/Objects/clinic/floatobject.c.h
@@ -38,6 +38,42 @@ float___trunc__(PyObject *self, PyObject *Py_UNUSED(ignored))
     return float___trunc___impl(self);
 }
 
+PyDoc_STRVAR(float___floor____doc__,
+"__floor__($self, /)\n"
+"--\n"
+"\n"
+"Return the floor as an Integral.");
+
+#define FLOAT___FLOOR___METHODDEF    \
+    {"__floor__", (PyCFunction)float___floor__, METH_NOARGS, float___floor____doc__},
+
+static PyObject *
+float___floor___impl(PyObject *self);
+
+static PyObject *
+float___floor__(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return float___floor___impl(self);
+}
+
+PyDoc_STRVAR(float___ceil____doc__,
+"__ceil__($self, /)\n"
+"--\n"
+"\n"
+"Return the ceiling as an Integral.");
+
+#define FLOAT___CEIL___METHODDEF    \
+    {"__ceil__", (PyCFunction)float___ceil__, METH_NOARGS, float___ceil____doc__},
+
+static PyObject *
+float___ceil___impl(PyObject *self);
+
+static PyObject *
+float___ceil__(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return float___ceil___impl(self);
+}
+
 PyDoc_STRVAR(float___round____doc__,
 "__round__($self, ndigits=None, /)\n"
 "--\n"
@@ -351,4 +387,4 @@ float___format__(PyObject *self, PyObject *arg)
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=1676433b9f04fbc9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=25fbbe253f44e2df input=a9049054013a1b77]*/
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 20a5155e07346..4fc412b43f7a3 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -905,6 +905,34 @@ float___trunc___impl(PyObject *self)
     return PyLong_FromDouble(wholepart);
 }
 
+/*[clinic input]
+float.__floor__
+
+Return the floor as an Integral.
+[clinic start generated code]*/
+
+static PyObject *
+float___floor___impl(PyObject *self)
+/*[clinic end generated code: output=e0551dbaea8c01d1 input=77bb13eb12e268df]*/
+{
+    double x = PyFloat_AS_DOUBLE(self);
+    return PyLong_FromDouble(floor(x));
+}
+
+/*[clinic input]
+float.__ceil__
+
+Return the ceiling as an Integral.
+[clinic start generated code]*/
+
+static PyObject *
+float___ceil___impl(PyObject *self)
+/*[clinic end generated code: output=a2fd8858f73736f9 input=79e41ae94aa0a516]*/
+{
+    double x = PyFloat_AS_DOUBLE(self);
+    return PyLong_FromDouble(ceil(x));
+}
+
 /* double_round: rounds a finite double to the closest multiple of
    10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
    ndigits <= 323).  Returns a Python float, or sets a Python error and
@@ -1828,6 +1856,8 @@ float___format___impl(PyObject *self, PyObject *format_spec)
 static PyMethodDef float_methods[] = {
     FLOAT_CONJUGATE_METHODDEF
     FLOAT___TRUNC___METHODDEF
+    FLOAT___FLOOR___METHODDEF
+    FLOAT___CEIL___METHODDEF
     FLOAT___ROUND___METHODDEF
     FLOAT_AS_INTEGER_RATIO_METHODDEF
     FLOAT_FROMHEX_METHODDEF



More information about the Python-checkins mailing list