Skip to content

Commit 0b36750

Browse files
committed
bpo-38629: implement __floor__ and __ceil__ for float
1 parent da6ce58 commit 0b36750

File tree

4 files changed

+97
-1
lines changed

4 files changed

+97
-1
lines changed

Lib/test/test_float.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,34 @@ def assertEqualAndEqualSign(self, a, b):
312312
# distinguishes -0.0 and 0.0.
313313
self.assertEqual((a, copysign(1.0, a)), (b, copysign(1.0, b)))
314314

315+
def test_float_floor(self):
316+
self.assertIsInstance(float(0.5).__floor__(), int)
317+
self.assertEqual(float(0.5).__floor__(), 0)
318+
self.assertEqual(float(1.0).__floor__(), 1)
319+
self.assertEqual(float(1.5).__floor__(), 1)
320+
self.assertEqual(float(-0.5).__floor__(), -1)
321+
self.assertEqual(float(-1.0).__floor__(), -1)
322+
self.assertEqual(float(-1.5).__floor__(), -2)
323+
self.assertEqual(float(1.23e167).__floor__(), 1.23e167)
324+
self.assertEqual(float(-1.23e167).__floor__(), -1.23e167)
325+
self.assertRaises(ValueError, float("nan").__floor__)
326+
self.assertRaises(OverflowError, float("inf").__floor__)
327+
self.assertRaises(OverflowError, float("-inf").__floor__)
328+
329+
def test_float_ceil(self):
330+
self.assertIsInstance(float(0.5).__ceil__(), int)
331+
self.assertEqual(float(0.5).__ceil__(), 1)
332+
self.assertEqual(float(1.0).__ceil__(), 1)
333+
self.assertEqual(float(1.5).__ceil__(), 2)
334+
self.assertEqual(float(-0.5).__ceil__(), 0)
335+
self.assertEqual(float(-1.0).__ceil__(), -1)
336+
self.assertEqual(float(-1.5).__ceil__(), -1)
337+
self.assertEqual(float(1.23e167).__ceil__(), 1.23e167)
338+
self.assertEqual(float(-1.23e167).__ceil__(), -1.23e167)
339+
self.assertRaises(ValueError, float("nan").__ceil__)
340+
self.assertRaises(OverflowError, float("inf").__ceil__)
341+
self.assertRaises(OverflowError, float("-inf").__ceil__)
342+
315343
@support.requires_IEEE_754
316344
def test_float_mod(self):
317345
# Check behaviour of % operator for IEEE 754 special cases.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Implementation of missing floor and ceil methods to float object -- by
2+
Batuhan Taskaya.

Objects/clinic/floatobject.c.h

Lines changed: 37 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/floatobject.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,34 @@ float___trunc___impl(PyObject *self)
923923
return PyLong_FromDouble(wholepart);
924924
}
925925

926+
/*[clinic input]
927+
float.__floor__
928+
929+
Return the floor as an Integral.
930+
[clinic start generated code]*/
931+
932+
static PyObject *
933+
float___floor___impl(PyObject *self)
934+
/*[clinic end generated code: output=e0551dbaea8c01d1 input=38c8fb1dd0b579b4]*/
935+
{
936+
double x = PyFloat_AsDouble(self);
937+
return PyLong_FromDouble(floor(x));
938+
}
939+
940+
/*[clinic input]
941+
float.__ceil__
942+
943+
Return the ceiling as an Integral.
944+
[clinic start generated code]*/
945+
946+
static PyObject *
947+
float___ceil___impl(PyObject *self)
948+
/*[clinic end generated code: output=a2fd8858f73736f9 input=e3d4c94c2b8c8675]*/
949+
{
950+
double x = PyFloat_AsDouble(self);
951+
return PyLong_FromDouble(ceil(x));
952+
}
953+
926954
/* double_round: rounds a finite double to the closest multiple of
927955
10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
928956
ndigits <= 323). Returns a Python float, or sets a Python error and
@@ -1847,6 +1875,8 @@ float___format___impl(PyObject *self, PyObject *format_spec)
18471875
static PyMethodDef float_methods[] = {
18481876
FLOAT_CONJUGATE_METHODDEF
18491877
FLOAT___TRUNC___METHODDEF
1878+
FLOAT___FLOOR___METHODDEF
1879+
FLOAT___CEIL___METHODDEF
18501880
FLOAT___ROUND___METHODDEF
18511881
FLOAT_AS_INTEGER_RATIO_METHODDEF
18521882
FLOAT_FROMHEX_METHODDEF

0 commit comments

Comments
 (0)