Mercurial > cpython-lru_cache-weakref
diff Objects/floatobject.c @ 26328:f3a69037fdf0 legacy-trunk
float_int(): Some systems raise an exception if a double is cast to
long but the double is too big to fit in a long. Prevent that. This
closes some recent bug or patch on SF, but SF is down now so I can't
say which.
Bugfix candidate.
| author | Tim Peters <tim.peters@gmail.com> |
|---|---|
| date | Thu, 21 Nov 2002 22:26:37 +0000 |
| parents | d31ddc66b1b5 |
| children | 5ba7934a7ba0 |
line wrap: on
line diff
--- a/Objects/floatobject.c Thu Nov 21 21:45:32 2002 +0000 +++ b/Objects/floatobject.c Thu Nov 21 22:26:37 2002 +0000 @@ -653,23 +653,25 @@ { double x = PyFloat_AsDouble(v); double wholepart; /* integral portion of x, rounded toward 0 */ - long aslong; /* (long)wholepart */ (void)modf(x, &wholepart); -#ifdef RISCOS - /* conversion from floating to integral type would raise exception */ - if (wholepart>LONG_MAX || wholepart<LONG_MIN) { - return float_long(v); + /* 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 PyInt_FromLong(aslong); } -#endif - /* doubles may have more bits than longs, or vice versa; and casting - to long may yield gibberish in either case. What really matters - is whether converting back to double again reproduces what we - started with. */ - aslong = (long)wholepart; - if ((double)aslong == wholepart) - return PyInt_FromLong(aslong); - return float_long(v); + return PyLong_FromDouble(wholepart); } static PyObject *
