mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991)
This commit is contained in:
parent
51edf8aaa2
commit
5fd5cb8d85
3 changed files with 70 additions and 41 deletions
|
|
@ -1013,12 +1013,6 @@ math_1(PyObject *arg, double (*func) (double), int can_overflow)
|
|||
return math_1_to_whatever(arg, func, PyFloat_FromDouble, 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue