Commit d6234141 authored by Raymond Hettinger's avatar Raymond Hettinger

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

parent 7b1ed663
...@@ -324,12 +324,17 @@ FUNC1(tanh, tanh, 0, ...@@ -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
Note 4: Intermediate values and partial sums are declared as long doubles regular doubles instead of extended long precision (80-bit) values. This
as a way to eliminate double rounding environments where the operations prevents double rounding because any addition or substraction of two doubles
are carried-out in extended precision but stored in double precision can be resolved exactly into double-sized hi and lo values. As long as the
variables. In some cases, this doesn't help because the compiler hi value gets forced into a double before yr and lo are computed, the extra
treats long doubles as doubles (i.e. the MS compiler for Win32 builds). 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: A similar implementation is in Modules/cmathmodule.c.
Be sure to update both when making changes.
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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment