diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-09-04 05:14:19 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-09-04 05:14:19 (GMT) |
commit | 9fffa3eea3a7e99b0179988e7a016a45bf63ab96 (patch) | |
tree | 1b891e323dff2790bcd2b74ad4071cb0d380803d /Objects/longobject.c | |
parent | 1832de4bc07e7ffd5938b41e8d7d8fcf8b5e12e2 (diff) | |
download | cpython-9fffa3eea3a7e99b0179988e7a016a45bf63ab96.zip cpython-9fffa3eea3a7e99b0179988e7a016a45bf63ab96.tar.gz cpython-9fffa3eea3a7e99b0179988e7a016a45bf63ab96.tar.bz2 |
Raise OverflowError when appropriate on long->float conversion. Most of
the fiddling is simply due to that no caller of PyLong_AsDouble ever
checked for failure (so that's fixing old bugs). PyLong_AsDouble is much
faster for big inputs now too, but that's more of a happy consequence
than a design goal.
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index b511928..e97ebd5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -531,27 +531,28 @@ _PyLong_AsScaledDouble(PyObject *vv, int *exponent) double PyLong_AsDouble(PyObject *vv) { - register PyLongObject *v; + int e; double x; - double multiplier = (double) (1L << SHIFT); - int i, sign; - + if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return -1; } - v = (PyLongObject *)vv; - i = v->ob_size; - sign = 1; - x = 0.0; - if (i < 0) { - sign = -1; - i = -(i); - } - while (--i >= 0) { - x = x*multiplier + (double)v->ob_digit[i]; - } - return x * sign; + x = _PyLong_AsScaledDouble(vv, &e); + if (x == -1.0 && PyErr_Occurred()) + return -1.0; + if (e > INT_MAX / SHIFT) + goto overflow; + errno = 0; + x = ldexp(x, e * SHIFT); + if (errno == ERANGE) + goto overflow; + return x; + +overflow: + PyErr_SetString(PyExc_OverflowError, + "long int too large to convert to float"); + return -1.0; } /* Create a new long (or int) object from a C pointer */ @@ -2098,9 +2099,9 @@ static PyObject * long_float(PyObject *v) { double result; - PyFPE_START_PROTECT("long_float", return 0) result = PyLong_AsDouble(v); - PyFPE_END_PROTECT(result) + if (result == -1.0 && PyErr_Occurred()) + return NULL; return PyFloat_FromDouble(result); } |