[Matrix-SIG] Problem with integer arrays?
dlr@postbox.ius.cs.cmu.edu
dlr@postbox.ius.cs.cmu.edu
Tue, 6 Oct 98 12:50:50 EDT
Charles Waldman wrote:
>> >>> a = Numeric.array((0,0))
>> >>> a**2
>> Traceback (innermost last):
>> File "<stdin>", line 1, in ?
>> OverflowError: math range error
In umathmodule.c, the function powll() has a range check:
> /* Overflow check: overflow will occur if log2(abs(x)) * n > nbits. */
On my machine, the math range error is happening when we take
log2(0) = -inf. I think the best fix is to put a test around the
overflow check so that it's not executed if x == 0. I've modified my
version of umathmodule.c, and it seems to work fine (diffs appended).
Also, I noticed this strange behavior yesterday:
>>> import Numeric
>>> Numeric.__version__
'1.4'
>>> a = Numeric.ones(5)
>>> a
array([1, 1, 1, 1, 1])
>>> (-1) * a
array([-1, 1, -1, 1, -1])
I've made and mildly tested a change to umathmodule.c which I think
fixes this too (see below).
Of course, I'd welcome corrections or comments.
David LaRose
-------------------------------------
Note: This diff is for Numeric 1.4, from the LLNLPython5 distribution
diff umathmodule.c umathmodule.orig.c
261,271c261,263
<
< /******Added by dlr@cs.cmu.edu, 10/6/98**********/
< if(x != 0) { /* Range check unnecessary & dangerous if x == 0 */
< /******End of Addition by dlr@cs.cmu.edu, 10/6/98**********/
< logtwox = log10 (fabs ( (double) x))/log10 ( (double) 2.0);
< if (logtwox * (double) n > (double) nbits)
< PyErr_SetString(PyExc_ArithmeticError, "Integer overflow in power.");
< /******Added by dlr@cs.cmu.edu, 10/6/98**********/
< } /* if(x != 0) */
< /******End of Addition by dlr@cs.cmu.edu, 10/6/98**********/
<
---
> logtwox = log10 (fabs ( (double) x))/log10 ( (double) 2.0);
> if (logtwox * (double) n > (double) nbits)
> PyErr_SetString(PyExc_ArithmeticError, "Integer overflow in power.");
439,441d430
< /********Added by dlr, 10/6/98*******/
< s = 1; /* reset sign flag */
< /********End of addition by dlr, 10/6/98*******/
546,548d534
< /********Added by dlr, 10/6/98*******/
< s = 1; /* reset sign flag */
< /********End of addition by dlr, 10/6/98*******/
653,655d638
< /********Added by dlr, 10/6/98*******/
< s = 1; /* reset sign flag */
< /********End of addition by dlr, 10/6/98*******/