diff options
author | Mark Wiebe <mwwiebe@gmail.com> | 2011-04-23 13:06:12 -0700 |
---|---|---|
committer | Mark Wiebe <mwwiebe@gmail.com> | 2011-04-23 13:07:00 -0700 |
commit | 5eae1f468fdcd1654e985ebfe5cd37479d41a06c (patch) | |
tree | e026bd992cf9148ab3edc4920bfc1f50419c2946 | |
parent | 566ace25f63985e0739bcc600c35336d3c66508c (diff) | |
download | numpy-5eae1f468fdcd1654e985ebfe5cd37479d41a06c.tar.gz |
BUG: Fix signed char assumption in einsum label parsing
-rw-r--r-- | numpy/core/src/multiarray/einsum.c.src | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/numpy/core/src/multiarray/einsum.c.src b/numpy/core/src/multiarray/einsum.c.src index 98a26c322..9898d00fa 100644 --- a/numpy/core/src/multiarray/einsum.c.src +++ b/numpy/core/src/multiarray/einsum.c.src @@ -1917,6 +1917,10 @@ parse_operand_subscripts(char *subscripts, int length, /* * Find any labels duplicated for this operand, and turn them * into negative offets to the axis to merge with. + * + * In C, the char type may be signed or unsigned, but with + * twos complement arithmetic the char is ok either way here, and + * later where it matters the char is cast to a signed char. */ for (idim = 0; idim < ndim-1; ++idim) { char *next; @@ -1928,7 +1932,7 @@ parse_operand_subscripts(char *subscripts, int length, ndim-idim-1); while (next != NULL) { /* The offset from next to out_labels[idim] (negative) */ - *next = (out_labels+idim)-next; + *next = (char)((out_labels+idim)-next); /* Search for the next matching label */ next = (char *)memchr(next+1, label, out_labels+ndim-1-next); @@ -2128,7 +2132,11 @@ get_single_op_view(PyArrayObject *op, int iop, char *labels, /* Match the labels in the operand with the output labels */ for (idim = 0; idim < ndim; ++idim) { - label = labels[idim]; + /* + * The char type may be either signed or unsigned, we + * need it to be signed here. + */ + label = (signed char)labels[idim]; /* If this label says to merge axes, get the actual label */ if (label < 0) { label = labels[idim+label]; @@ -2226,7 +2234,11 @@ get_combined_dims_view(PyArrayObject *op, int iop, char *labels) /* Copy the dimensions and strides, except when collapsing */ icombine = 0; for (idim = 0; idim < ndim; ++idim) { - label = labels[idim]; + /* + * The char type may be either signed or unsigned, we + * need it to be signed here. + */ + label = (signed char)labels[idim]; /* If this label says to merge axes, get the actual label */ if (label < 0) { combineoffset = label; @@ -2877,10 +2889,15 @@ PyArray_EinsteinSum(char *subscripts, npy_intp nop, } } - /* Check whether any dimensions need to be combined */ + /* + * Check whether any dimensions need to be combined + * + * The char type may be either signed or unsigned, we + * need it to be signed here. + */ combine = 0; for (idim = 0; idim < ndim; ++idim) { - if (labels[idim] < 0) { + if ((signed char)labels[idim] < 0) { combine = 1; } } |