[Python-checkins] r64072 - in python/branches/tlee-ast-optimize: Doc/library/stdtypes.rst Lib/test/test_set.py Misc/NEWS Modules/mathmodule.c Objects/setobject.c
thomas.lee
python-checkins at python.org
Tue Jun 10 16:31:48 CEST 2008
Author: thomas.lee
Date: Tue Jun 10 16:31:47 2008
New Revision: 64072
Log:
Merged revisions 64053-64056 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r64054 | raymond.hettinger | 2008-06-09 21:24:47 +1000 (Mon, 09 Jun 2008) | 1 line
Unhappy buildbots. Revert 64052. Long doubles have unexpected effects on some builds.
........
r64055 | raymond.hettinger | 2008-06-09 23:07:27 +1000 (Mon, 09 Jun 2008) | 1 line
Let set.intersection() and set.intersection_update() take multiple input arguments.
........
Modified:
python/branches/tlee-ast-optimize/ (props changed)
python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
python/branches/tlee-ast-optimize/Lib/test/test_set.py
python/branches/tlee-ast-optimize/Misc/NEWS
python/branches/tlee-ast-optimize/Modules/mathmodule.c
python/branches/tlee-ast-optimize/Objects/setobject.c
Modified: python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst (original)
+++ python/branches/tlee-ast-optimize/Doc/library/stdtypes.rst Tue Jun 10 16:31:47 2008
@@ -1575,11 +1575,14 @@
.. versionchanged:: 2.6
Accepts multiple input iterables.
- .. method:: intersection(other)
- set & other
+ .. method:: intersection(other, ...)
+ set & other & ...
Return a new set with elements common to both sets.
+ .. versionchanged:: 2.6
+ Accepts multiple input iterables.
+
.. method:: difference(other)
set - other
@@ -1639,11 +1642,14 @@
.. versionchanged:: 2.6
Accepts multiple input iterables.
- .. method:: intersection_update(other)
- set &= other
+ .. method:: intersection_update(other, ...)
+ set &= other & ...
Update the set, keeping only elements found in it and *other*.
+ .. versionchanged:: 2.6
+ Accepts multiple input iterables.
+
.. method:: difference_update(other)
set -= other
Modified: python/branches/tlee-ast-optimize/Lib/test/test_set.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_set.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_set.py Tue Jun 10 16:31:47 2008
@@ -103,6 +103,7 @@
self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set(''))
self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc'))
self.assertEqual(self.thetype('abcba').intersection(C('ef')), set(''))
+ self.assertEqual(self.thetype('abcba').intersection(C('cbcf'), C('bag')), set('b'))
def test_isdisjoint(self):
def f(s1, s2):
@@ -429,6 +430,11 @@
s = self.thetype('abcba')
self.assertEqual(s.intersection_update(C(p)), None)
self.assertEqual(s, set(q))
+ ss = 'abcba'
+ s = self.thetype(ss)
+ t = 'cbc'
+ self.assertEqual(s.intersection_update(C(p), C(t)), None)
+ self.assertEqual(s, set('abcba')&set(p)&set(t))
def test_iand(self):
self.s &= set(self.otherword)
Modified: python/branches/tlee-ast-optimize/Misc/NEWS
==============================================================================
--- python/branches/tlee-ast-optimize/Misc/NEWS (original)
+++ python/branches/tlee-ast-optimize/Misc/NEWS Tue Jun 10 16:31:47 2008
@@ -12,7 +12,8 @@
Core and Builtins
-----------------
-- The set methods, update() and union() now accept multiple arguments.
+- Several set methods now accept multiple arguments: update(), union(),
+ intersection() and intersection_update().
- Issue #2898: Added sys.getsizeof() to retrieve size of objects in bytes.
Modified: python/branches/tlee-ast-optimize/Modules/mathmodule.c
==============================================================================
--- python/branches/tlee-ast-optimize/Modules/mathmodule.c (original)
+++ python/branches/tlee-ast-optimize/Modules/mathmodule.c Tue Jun 10 16:31:47 2008
@@ -324,12 +324,17 @@
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.
+ 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
- as a way to eliminate double rounding environments where the operations
- 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 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()
because the start argument doesn't make sense in the context of
@@ -342,28 +347,28 @@
/* Extend the partials array p[] by doubling its size. */
static int /* non-zero on error */
-_sum_realloc(long double **p_ptr, Py_ssize_t n,
- long double *ps, Py_ssize_t *m_ptr)
+_sum_realloc(double **p_ptr, Py_ssize_t n,
+ double *ps, Py_ssize_t *m_ptr)
{
void *v = NULL;
Py_ssize_t m = *m_ptr;
- m += m; /* long double */
- if (n < m && m < (PY_SSIZE_T_MAX / sizeof(long double))) {
- long double *p = *p_ptr;
+ m += m; /* double */
+ if (n < m && m < (PY_SSIZE_T_MAX / sizeof(double))) {
+ double *p = *p_ptr;
if (p == ps) {
- v = PyMem_Malloc(sizeof(long double) * m);
+ v = PyMem_Malloc(sizeof(double) * m);
if (v != NULL)
- memcpy(v, ps, sizeof(long double) * n);
+ memcpy(v, ps, sizeof(double) * n);
}
else
- v = PyMem_Realloc(p, sizeof(long double) * m);
+ v = PyMem_Realloc(p, sizeof(double) * m);
}
if (v == NULL) { /* size overflow or no memory */
PyErr_SetString(PyExc_MemoryError, "math sum partials");
return 1;
}
- *p_ptr = (long double*) v;
+ *p_ptr = (double*) v;
*m_ptr = m;
return 0;
}
@@ -403,8 +408,8 @@
{
PyObject *item, *iter, *sum = NULL;
Py_ssize_t i, j, n = 0, m = NUM_PARTIALS;
- long double x, y, t, ps[NUM_PARTIALS], *p = ps;
- volatile long double hi, yr, lo;
+ double x, y, t, ps[NUM_PARTIALS], *p = ps;
+ volatile double hi, yr, lo;
iter = PyObject_GetIter(seq);
if (iter == NULL)
@@ -423,7 +428,7 @@
goto _sum_error;
break;
}
- x = (long double)PyFloat_AsDouble(item);
+ x = PyFloat_AsDouble(item);
Py_DECREF(item);
if (PyErr_Occurred())
goto _sum_error;
@@ -490,7 +495,7 @@
goto _sum_error;
}
}
- sum = PyFloat_FromDouble((double)hi);
+ sum = PyFloat_FromDouble(hi);
_sum_error:
PyFPE_END_PROTECT(hi)
@@ -507,7 +512,6 @@
Return an accurate floating point sum of values in the iterable.\n\
Assumes IEEE-754 floating point arithmetic.");
-
static PyObject *
math_factorial(PyObject *self, PyObject *arg)
{
Modified: python/branches/tlee-ast-optimize/Objects/setobject.c
==============================================================================
--- python/branches/tlee-ast-optimize/Objects/setobject.c (original)
+++ python/branches/tlee-ast-optimize/Objects/setobject.c Tue Jun 10 16:31:47 2008
@@ -1306,6 +1306,26 @@
return (PyObject *)result;
}
+static PyObject *
+set_intersection_multi(PySetObject *so, PyObject *args)
+{
+ Py_ssize_t i;
+ PyObject *result = (PyObject *)so;
+
+ Py_INCREF(so);
+ for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
+ PyObject *other = PyTuple_GET_ITEM(args, i);
+ PyObject *newresult = set_intersection((PySetObject *)result, other);
+ if (newresult == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_DECREF(result);
+ result = newresult;
+ }
+ return result;
+}
+
PyDoc_STRVAR(intersection_doc,
"Return the intersection of two sets as a new set.\n\
\n\
@@ -1324,6 +1344,19 @@
Py_RETURN_NONE;
}
+static PyObject *
+set_intersection_update_multi(PySetObject *so, PyObject *args)
+{
+ PyObject *tmp;
+
+ tmp = set_intersection_multi(so, args);
+ if (tmp == NULL)
+ return NULL;
+ set_swap_bodies(so, (PySetObject *)tmp);
+ Py_DECREF(tmp);
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(intersection_update_doc,
"Update a set with the intersection of itself and another.");
@@ -1946,9 +1979,9 @@
difference_doc},
{"difference_update", (PyCFunction)set_difference_update, METH_O,
difference_update_doc},
- {"intersection",(PyCFunction)set_intersection, METH_O,
+ {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
intersection_doc},
- {"intersection_update",(PyCFunction)set_intersection_update, METH_O,
+ {"intersection_update",(PyCFunction)set_intersection_update_multi, METH_VARARGS,
intersection_update_doc},
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
isdisjoint_doc},
@@ -2073,7 +2106,7 @@
copy_doc},
{"difference", (PyCFunction)set_difference, METH_O,
difference_doc},
- {"intersection",(PyCFunction)set_intersection, METH_O,
+ {"intersection",(PyCFunction)set_intersection_multi, METH_VARARGS,
intersection_doc},
{"isdisjoint", (PyCFunction)set_isdisjoint, METH_O,
isdisjoint_doc},
More information about the Python-checkins
mailing list