| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -240,6 +240,13 @@ def result_check(expected, got, ulp_tol=5, abs_tol=0.0): | |||
| 240 | 240 | else: | |
| 241 | 241 | return None | |
| 242 | 242 | ||
| 243 | + class FloatLike: | ||
| 244 | + def __init__(self, value): | ||
| 245 | + self.value = value | ||
| 246 | + | ||
| 247 | + def __float__(self): | ||
| 248 | + return self.value | ||
| 249 | + | ||
| 243 | 250 | class IntSubclass(int): | |
| 244 | 251 | pass | |
| 245 | 252 | ||
@@ -397,22 +404,29 @@ def testAtan2(self): | |||
| 397 | 404 | def testCeil(self): | |
| 398 | 405 | self.assertRaises(TypeError, math.ceil) | |
| 399 | 406 | self.assertEqual(int, type(math.ceil(0.5))) | |
| 400 | - self.ftest('ceil(0.5)', math.ceil(0.5), 1) | ||
| 401 | - self.ftest('ceil(1.0)', math.ceil(1.0), 1) | ||
| 402 | - self.ftest('ceil(1.5)', math.ceil(1.5), 2) | ||
| 403 | - self.ftest('ceil(-0.5)', math.ceil(-0.5), 0) | ||
| 404 | - self.ftest('ceil(-1.0)', math.ceil(-1.0), -1) | ||
| 405 | - self.ftest('ceil(-1.5)', math.ceil(-1.5), -1) | ||
| 407 | + self.assertEqual(math.ceil(0.5), 1) | ||
| 408 | + self.assertEqual(math.ceil(1.0), 1) | ||
| 409 | + self.assertEqual(math.ceil(1.5), 2) | ||
| 410 | + self.assertEqual(math.ceil(-0.5), 0) | ||
| 411 | + self.assertEqual(math.ceil(-1.0), -1) | ||
| 412 | + self.assertEqual(math.ceil(-1.5), -1) | ||
| 413 | + self.assertEqual(math.ceil(0.0), 0) | ||
| 414 | + self.assertEqual(math.ceil(-0.0), 0) | ||
| 406 | 415 | #self.assertEqual(math.ceil(INF), INF) | |
| 407 | 416 | #self.assertEqual(math.ceil(NINF), NINF) | |
| 408 | 417 | #self.assertTrue(math.isnan(math.ceil(NAN))) | |
| 409 | 418 | ||
| 410 | 419 | class TestCeil: | |
| 411 | 420 | def __ceil__(self): | |
| 412 | 421 | return 42 | |
| 422 | + class FloatCeil(float): | ||
| 423 | + def __ceil__(self): | ||
| 424 | + return 42 | ||
| 413 | 425 | class TestNoCeil: | |
| 414 | 426 | pass | |
| 415 | - self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42) | ||
| 427 | + self.assertEqual(math.ceil(TestCeil()), 42) | ||
| 428 | + self.assertEqual(math.ceil(FloatCeil()), 42) | ||
| 429 | + self.assertEqual(math.ceil(FloatLike(42.5)), 43) | ||
| 416 | 430 | self.assertRaises(TypeError, math.ceil, TestNoCeil()) | |
| 417 | 431 | ||
| 418 | 432 | t = TestNoCeil() | |
@@ -536,26 +550,27 @@ def testFactorialHugeInputs(self): | |||
| 536 | 550 | def testFloor(self): | |
| 537 | 551 | self.assertRaises(TypeError, math.floor) | |
| 538 | 552 | self.assertEqual(int, type(math.floor(0.5))) | |
| 539 | - self.ftest('floor(0.5)', math.floor(0.5), 0) | ||
| 540 | - self.ftest('floor(1.0)', math.floor(1.0), 1) | ||
| 541 | - self.ftest('floor(1.5)', math.floor(1.5), 1) | ||
| 542 | - self.ftest('floor(-0.5)', math.floor(-0.5), -1) | ||
| 543 | - self.ftest('floor(-1.0)', math.floor(-1.0), -1) | ||
| 544 | - self.ftest('floor(-1.5)', math.floor(-1.5), -2) | ||
| 545 | - # pow() relies on floor() to check for integers | ||
| 546 | - # This fails on some platforms - so check it here | ||
| 547 | - self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167) | ||
| 548 | - self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167) | ||
| 553 | + self.assertEqual(math.floor(0.5), 0) | ||
| 554 | + self.assertEqual(math.floor(1.0), 1) | ||
| 555 | + self.assertEqual(math.floor(1.5), 1) | ||
| 556 | + self.assertEqual(math.floor(-0.5), -1) | ||
| 557 | + self.assertEqual(math.floor(-1.0), -1) | ||
| 558 | + self.assertEqual(math.floor(-1.5), -2) | ||
| 549 | 559 | #self.assertEqual(math.ceil(INF), INF) | |
| 550 | 560 | #self.assertEqual(math.ceil(NINF), NINF) | |
| 551 | 561 | #self.assertTrue(math.isnan(math.floor(NAN))) | |
| 552 | 562 | ||
| 553 | 563 | class TestFloor: | |
| 554 | 564 | def __floor__(self): | |
| 555 | 565 | return 42 | |
| 566 | + class FloatFloor(float): | ||
| 567 | + def __floor__(self): | ||
| 568 | + return 42 | ||
| 556 | 569 | class TestNoFloor: | |
| 557 | 570 | pass | |
| 558 | - self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42) | ||
| 571 | + self.assertEqual(math.floor(TestFloor()), 42) | ||
| 572 | + self.assertEqual(math.floor(FloatFloor()), 42) | ||
| 573 | + self.assertEqual(math.floor(FloatLike(41.9)), 41) | ||
| 559 | 574 | self.assertRaises(TypeError, math.floor, TestNoFloor()) | |
| 560 | 575 | ||
| 561 | 576 | t = TestNoFloor() | |
@@ -1448,17 +1463,21 @@ def test_trunc(self): | |||
| 1448 | 1463 | self.assertEqual(math.trunc(-0.999999), -0) | |
| 1449 | 1464 | self.assertEqual(math.trunc(-100.999), -100) | |
| 1450 | 1465 | ||
| 1451 | - class TestTrunc(object): | ||
| 1466 | + class TestTrunc: | ||
| 1452 | 1467 | def __trunc__(self): | |
| 1453 | 1468 | return 23 | |
| 1454 | - | ||
| 1455 | - class TestNoTrunc(object): | ||
| 1469 | + class FloatTrunc(float): | ||
| 1470 | + def __trunc__(self): | ||
| 1471 | + return 23 | ||
| 1472 | + class TestNoTrunc: | ||
| 1456 | 1473 | pass | |
| 1457 | 1474 | ||
| 1458 | 1475 | self.assertEqual(math.trunc(TestTrunc()), 23) | |
| 1476 | + self.assertEqual(math.trunc(FloatTrunc()), 23) | ||
| 1459 | 1477 | ||
| 1460 | 1478 | self.assertRaises(TypeError, math.trunc) | |
| 1461 | 1479 | self.assertRaises(TypeError, math.trunc, 1, 2) | |
| 1480 | + self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) | ||
| 1462 | 1481 | self.assertRaises(TypeError, math.trunc, TestNoTrunc()) | |
| 1463 | 1482 | ||
| 1464 | 1483 | def testIsfinite(self): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Optimized :func:`math.floor()`, :func:`math.ceil()` and :func:`math.trunc()` | ||
| 2 | + for floats. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1013,12 +1013,6 @@ math_1(PyObject *arg, double (*func) (double), int can_overflow) | |||
| 1013 | 1013 | return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); | |
| 1014 | 1014 | } | |
| 1015 | 1015 | ||
| 1016 | - static PyObject * | ||
| 1017 | - math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) | ||
| 1018 | - { | ||
| 1019 | - return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); | ||
| 1020 | - } | ||
| 1021 | - | ||
| 1022 | 1016 | static PyObject * | |
| 1023 | 1017 | math_2(PyObject *const *args, Py_ssize_t nargs, | |
| 1024 | 1018 | double (*func) (double, double), const char *funcname) | |
@@ -1112,17 +1106,22 @@ math_ceil(PyObject *module, PyObject *number) | |||
| 1112 | 1106 | /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ | |
| 1113 | 1107 | { | |
| 1114 | 1108 | _Py_IDENTIFIER(__ceil__); | |
| 1115 | - PyObject *method, *result; | ||
| 1116 | 1109 | ||
| 1117 | - method = _PyObject_LookupSpecial(number, &PyId___ceil__); | ||
| 1118 | - if (method == NULL) { | ||
| 1110 | + if (!PyFloat_CheckExact(number)) { | ||
| 1111 | + PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__); | ||
| 1112 | + if (method != NULL) { | ||
| 1113 | + PyObject *result = _PyObject_CallNoArg(method); | ||
| 1114 | + Py_DECREF(method); | ||
| 1115 | + return result; | ||
| 1116 | + } | ||
| 1119 | 1117 | if (PyErr_Occurred()) | |
| 1120 | 1118 | return NULL; | |
| 1121 | - return math_1_to_int(number, ceil, 0); | ||
| 1122 | 1119 | } | |
| 1123 | - result = _PyObject_CallNoArg(method); | ||
| 1124 | - Py_DECREF(method); | ||
| 1125 | - return result; | ||
| 1120 | + double x = PyFloat_AsDouble(number); | ||
| 1121 | + if (x == -1.0 && PyErr_Occurred()) | ||
| 1122 | + return NULL; | ||
| 1123 | + | ||
| 1124 | + return PyLong_FromDouble(ceil(x)); | ||
| 1126 | 1125 | } | |
| 1127 | 1126 | ||
| 1128 | 1127 | FUNC2(copysign, copysign, | |
@@ -1170,17 +1169,22 @@ math_floor(PyObject *module, PyObject *number) | |||
| 1170 | 1169 | /*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/ | |
| 1171 | 1170 | { | |
| 1172 | 1171 | _Py_IDENTIFIER(__floor__); | |
| 1173 | - PyObject *method, *result; | ||
| 1174 | 1172 | ||
| 1175 | - method = _PyObject_LookupSpecial(number, &PyId___floor__); | ||
| 1176 | - if (method == NULL) { | ||
| 1173 | + if (!PyFloat_CheckExact(number)) { | ||
| 1174 | + PyObject *method = _PyObject_LookupSpecial(number, &PyId___floor__); | ||
| 1175 | + if (method != NULL) { | ||
| 1176 | + PyObject *result = _PyObject_CallNoArg(method); | ||
| 1177 | + Py_DECREF(method); | ||
| 1178 | + return result; | ||
| 1179 | + } | ||
| 1177 | 1180 | if (PyErr_Occurred()) | |
| 1178 | 1181 | return NULL; | |
| 1179 | - return math_1_to_int(number, floor, 0); | ||
| 1180 | 1182 | } | |
| 1181 | - result = _PyObject_CallNoArg(method); | ||
| 1182 | - Py_DECREF(method); | ||
| 1183 | - return result; | ||
| 1183 | + double x = PyFloat_AsDouble(number); | ||
| 1184 | + if (x == -1.0 && PyErr_Occurred()) | ||
| 1185 | + return NULL; | ||
| 1186 | + | ||
| 1187 | + return PyLong_FromDouble(floor(x)); | ||
| 1184 | 1188 | } | |
| 1185 | 1189 | ||
| 1186 | 1190 | FUNC1A(gamma, m_tgamma, | |
@@ -2061,6 +2065,10 @@ math_trunc(PyObject *module, PyObject *x) | |||
| 2061 | 2065 | _Py_IDENTIFIER(__trunc__); | |
| 2062 | 2066 | PyObject *trunc, *result; | |
| 2063 | 2067 | ||
| 2068 | + if (PyFloat_CheckExact(x)) { | ||
| 2069 | + return PyFloat_Type.tp_as_number->nb_int(x); | ||
| 2070 | + } | ||
| 2071 | + | ||
| 2064 | 2072 | if (Py_TYPE(x)->tp_dict == NULL) { | |
| 2065 | 2073 | if (PyType_Ready(Py_TYPE(x)) < 0) | |
| 2066 | 2074 | return NULL; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments