Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.

This commit is contained in:
Raymond Hettinger 2008-06-09 11:24:47 +00:00
parent 7b1ed66372
commit d623414141

View file

@ -324,12 +324,17 @@ FUNC1(tanh, tanh, 0,
Note 3: The itermediate values lo, yr, and hi are declared volatile so Note 3: The itermediate values lo, yr, and hi are declared volatile so
aggressive compilers won't algebraicly reduce lo to always be exactly 0.0. aggressive compilers won't algebraicly reduce lo to always be exactly 0.0.
Also, the volatile declaration forces the values to be stored in memory as
regular doubles instead of extended long precision (80-bit) values. This
prevents double rounding because any addition or substraction of two doubles
can be resolved exactly into double-sized hi and lo values. As long as the
hi value gets forced into a double before yr and lo are computed, the extra
bits in downstream extended precision operations (x87 for example) will be
exactly zero and therefore can be losslessly stored back into a double,
thereby preventing double rounding.
Note 4: Intermediate values and partial sums are declared as long doubles Note 4: A similar implementation is in Modules/cmathmodule.c.
as a way to eliminate double rounding environments where the operations Be sure to update both when making changes.
are carried-out in extended precision but stored in double precision
variables. In some cases, this doesn't help because the compiler
treats long doubles as doubles (i.e. the MS compiler for Win32 builds).
Note 5: The signature of math.sum() differs from __builtin__.sum() Note 5: The signature of math.sum() differs from __builtin__.sum()
because the start argument doesn't make sense in the context of because the start argument doesn't make sense in the context of
@ -342,28 +347,28 @@ FUNC1(tanh, tanh, 0,
/* Extend the partials array p[] by doubling its size. */ /* Extend the partials array p[] by doubling its size. */
static int /* non-zero on error */ static int /* non-zero on error */
_sum_realloc(long double **p_ptr, Py_ssize_t n, _sum_realloc(double **p_ptr, Py_ssize_t n,
long double *ps, Py_ssize_t *m_ptr) double *ps, Py_ssize_t *m_ptr)
{ {
void *v = NULL; void *v = NULL;
Py_ssize_t m = *m_ptr; Py_ssize_t m = *m_ptr;
m += m; /* long double */ m += m; /* double */
if (n < m && m < (PY_SSIZE_T_MAX / sizeof(long double))) { if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) {
long double *p = *p_ptr; double *p = *p_ptr;
if (p == ps) { if (p == ps) {
v = PyMem_Malloc(sizeof(long double) * m); v = PyMem_Malloc(sizeof(double) * m);
if (v != NULL) if (v != NULL)
memcpy(v, ps, sizeof(long double) * n); memcpy(v, ps, sizeof(double) * n);
} }
else else
v = PyMem_Realloc(p, sizeof(long double) * m); v = PyMem_Realloc(p, sizeof(double) * m);
} }
if (v == NULL) { /* size overflow or no memory */ if (v == NULL) { /* size overflow or no memory */
PyErr_SetString(PyExc_MemoryError, "math sum partials"); PyErr_SetString(PyExc_MemoryError, "math sum partials");
return 1; return 1;
} }
*p_ptr = (long double*) v; *p_ptr = (double*) v;
*m_ptr = m; *m_ptr = m;
return 0; return 0;
} }
@ -403,8 +408,8 @@ math_sum(PyObject *self, PyObject *seq)
{ {
PyObject *item, *iter, *sum = NULL; PyObject *item, *iter, *sum = NULL;
Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
long double x, y, t, ps[NUM_PARTIALS], *p = ps; double x, y, t, ps[NUM_PARTIALS], *p = ps;
volatile long double hi, yr, lo; volatile double hi, yr, lo;
iter = PyObject_GetIter(seq); iter = PyObject_GetIter(seq);
if (iter == NULL) if (iter == NULL)
@ -423,7 +428,7 @@ math_sum(PyObject *self, PyObject *seq)
goto _sum_error; goto _sum_error;
break; break;
} }
x = (long double)PyFloat_AsDouble(item); x = PyFloat_AsDouble(item);
Py_DECREF(item); Py_DECREF(item);
if (PyErr_Occurred()) if (PyErr_Occurred())
goto _sum_error; goto _sum_error;
@ -490,7 +495,7 @@ math_sum(PyObject *self, PyObject *seq)
goto _sum_error; goto _sum_error;
} }
} }
sum = PyFloat_FromDouble((double)hi); sum = PyFloat_FromDouble(hi);
_sum_error: _sum_error:
PyFPE_END_PROTECT(hi) PyFPE_END_PROTECT(hi)
@ -507,7 +512,6 @@ PyDoc_STRVAR(math_sum_doc,
Return an accurate floating point sum of values in the iterable.\n\ Return an accurate floating point sum of values in the iterable.\n\
Assumes IEEE-754 floating point arithmetic."); Assumes IEEE-754 floating point arithmetic.");
static PyObject * static PyObject *
math_factorial(PyObject *self, PyObject *arg) math_factorial(PyObject *self, PyObject *arg)
{ {