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.
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index 236f4d5..7404993 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -522,6 +522,8 @@
 	}
 	else if (PyLong_Check(*pw)) {
 		cval.real = PyLong_AsDouble(*pw);
+		if (cval.real == -1.0 && PyErr_Occurred())
+			return -1;
 		*pw = PyComplex_FromCComplex(cval);
 		Py_INCREF(*pv);
 		return 0;
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 478e131..8443aff 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -271,18 +271,19 @@
 		return obj;
 
 static int
-convert_to_double(PyObject **v,
-		  double *dbl)
+convert_to_double(PyObject **v, double *dbl)
 {
 	register PyObject *obj = *v;
-	
+
 	if (PyInt_Check(obj)) {
 		*dbl = (double)PyInt_AS_LONG(obj);
 	}
 	else if (PyLong_Check(obj)) {
-		PyFPE_START_PROTECT("convert_to_double", {*v=NULL;return -1;})
 		*dbl = PyLong_AsDouble(obj);
-		PyFPE_END_PROTECT(*dbl)
+		if (*dbl == -1.0 && PyErr_Occurred()) {
+			*v = NULL;
+			return -1;
+		}
 	}
 	else {
 		Py_INCREF(Py_NotImplemented);
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 @@
 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 @@
 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);
 }