mirror of
https://github.com/python/cpython.git
synced 2025-11-25 04:34:37 +00:00
bpo-37986: Improve perfomance of PyLong_FromDouble() (GH-15611)
* bpo-37986: Improve perfomance of PyLong_FromDouble() * Use strict bound check for safety and symmetry * Remove possibly outdated performance claims Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
This commit is contained in:
parent
1c2fa78156
commit
86a93fddf7
3 changed files with 19 additions and 23 deletions
|
|
@ -862,27 +862,7 @@ static PyObject *
|
|||
float___trunc___impl(PyObject *self)
|
||||
/*[clinic end generated code: output=dd3e289dd4c6b538 input=591b9ba0d650fdff]*/
|
||||
{
|
||||
double x = PyFloat_AsDouble(self);
|
||||
double wholepart; /* integral portion of x, rounded toward 0 */
|
||||
|
||||
(void)modf(x, &wholepart);
|
||||
/* Try to get out cheap if this fits in a Python int. The attempt
|
||||
* to cast to long must be protected, as C doesn't define what
|
||||
* happens if the double is too big to fit in a long. Some rare
|
||||
* systems raise an exception then (RISCOS was mentioned as one,
|
||||
* and someone using a non-default option on Sun also bumped into
|
||||
* that). Note that checking for >= and <= LONG_{MIN,MAX} would
|
||||
* still be vulnerable: if a long has more bits of precision than
|
||||
* a double, casting MIN/MAX to double may yield an approximation,
|
||||
* and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would
|
||||
* yield true from the C expression wholepart<=LONG_MAX, despite
|
||||
* that wholepart is actually greater than LONG_MAX.
|
||||
*/
|
||||
if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
|
||||
const long aslong = (long)wholepart;
|
||||
return PyLong_FromLong(aslong);
|
||||
}
|
||||
return PyLong_FromDouble(wholepart);
|
||||
return PyLong_FromDouble(PyFloat_AS_DOUBLE(self));
|
||||
}
|
||||
|
||||
/*[clinic input]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue