summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2019-11-16 16:00:57 (GMT)
committerGitHub <noreply@github.com>2019-11-16 16:00:57 (GMT)
commit5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203 (patch)
tree99ac87736a8b6906bd7d4faeccd1a0d5cebfdb6e /Modules
parent51edf8aaa2e17626f9690ed29d25945fc03016b9 (diff)
downloadcpython-5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203.zip
cpython-5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203.tar.gz
cpython-5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203.tar.bz2
bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991)
Diffstat (limited to 'Modules')
-rw-r--r--Modules/mathmodule.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index e1b46ec..eaaeedb 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1014,12 +1014,6 @@ math_1(PyObject *arg, double (*func) (double), int can_overflow)
}
static PyObject *
-math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow)
-{
- return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow);
-}
-
-static PyObject *
math_2(PyObject *const *args, Py_ssize_t nargs,
double (*func) (double, double), const char *funcname)
{
@@ -1112,17 +1106,22 @@ math_ceil(PyObject *module, PyObject *number)
/*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/
{
_Py_IDENTIFIER(__ceil__);
- PyObject *method, *result;
- method = _PyObject_LookupSpecial(number, &PyId___ceil__);
- if (method == NULL) {
+ if (!PyFloat_CheckExact(number)) {
+ PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__);
+ if (method != NULL) {
+ PyObject *result = _PyObject_CallNoArg(method);
+ Py_DECREF(method);
+ return result;
+ }
if (PyErr_Occurred())
return NULL;
- return math_1_to_int(number, ceil, 0);
}
- result = _PyObject_CallNoArg(method);
- Py_DECREF(method);
- return result;
+ double x = PyFloat_AsDouble(number);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+
+ return PyLong_FromDouble(ceil(x));
}
FUNC2(copysign, copysign,
@@ -1170,17 +1169,22 @@ math_floor(PyObject *module, PyObject *number)
/*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/
{
_Py_IDENTIFIER(__floor__);
- PyObject *method, *result;
- method = _PyObject_LookupSpecial(number, &PyId___floor__);
- if (method == NULL) {
+ if (!PyFloat_CheckExact(number)) {
+ PyObject *method = _PyObject_LookupSpecial(number, &PyId___floor__);
+ if (method != NULL) {
+ PyObject *result = _PyObject_CallNoArg(method);
+ Py_DECREF(method);
+ return result;
+ }
if (PyErr_Occurred())
return NULL;
- return math_1_to_int(number, floor, 0);
}
- result = _PyObject_CallNoArg(method);
- Py_DECREF(method);
- return result;
+ double x = PyFloat_AsDouble(number);
+ if (x == -1.0 && PyErr_Occurred())
+ return NULL;
+
+ return PyLong_FromDouble(floor(x));
}
FUNC1A(gamma, m_tgamma,
@@ -2061,6 +2065,10 @@ math_trunc(PyObject *module, PyObject *x)
_Py_IDENTIFIER(__trunc__);
PyObject *trunc, *result;
+ if (PyFloat_CheckExact(x)) {
+ return PyFloat_Type.tp_as_number->nb_int(x);
+ }
+
if (Py_TYPE(x)->tp_dict == NULL) {
if (PyType_Ready(Py_TYPE(x)) < 0)
return NULL;