summaryrefslogtreecommitdiffstats
path: root/Objects/longobject.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-09-04 05:14:19 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-09-04 05:14:19 (GMT)
commit9fffa3eea3a7e99b0179988e7a016a45bf63ab96 (patch)
tree1b891e323dff2790bcd2b74ad4071cb0d380803d /Objects/longobject.c
parent1832de4bc07e7ffd5938b41e8d7d8fcf8b5e12e2 (diff)
downloadcpython-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.c37
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);
}