mirror of
https://github.com/python/cpython.git
synced 2025-11-28 14:11:15 +00:00
Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
This commit is contained in:
parent
7b1ed66372
commit
d623414141
1 changed files with 23 additions and 19 deletions
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue