diff options
author | Eric Moore <ewm@redtetrahedron.org> | 2016-03-22 08:53:43 -0400 |
---|---|---|
committer | Eric Moore <ewm@redtetrahedron.org> | 2016-03-22 08:53:43 -0400 |
commit | 58ff38a547e59e2e8f8278d445f66c1091f1299a (patch) | |
tree | 8ecfedf8d1b2b7660ae460eb94306e27669d64f0 | |
parent | 5c24db244ec8a8d7e4ca2f823b0ba71b7d4dff3d (diff) | |
download | python-numpy-58ff38a547e59e2e8f8278d445f66c1091f1299a.tar.gz python-numpy-58ff38a547e59e2e8f8278d445f66c1091f1299a.tar.bz2 python-numpy-58ff38a547e59e2e8f8278d445f66c1091f1299a.zip |
BUG: scalar integer negative powers gave wrong results.
np.int8(4)**np.int8(-4) gave inf. Since we result a float or
double for these cases, just call those power routines. This
prevents integer overflow from resulting in a divide by zero and
the old nonsense result.
-rw-r--r-- | numpy/core/src/umath/scalarmath.c.src | 6 | ||||
-rw-r--r-- | numpy/core/tests/test_scalarmath.py | 18 |
2 files changed, 22 insertions, 2 deletions
diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src index 77520abf5..c651383eb 100644 --- a/numpy/core/src/umath/scalarmath.c.src +++ b/numpy/core/src/umath/scalarmath.c.src @@ -936,6 +936,9 @@ static PyObject * * Half, Float, Double, LongDouble, * CFloat, CDouble, CLongDouble# * + * #oname = float*4, double*6, half, float, double, longdouble, + * cfloat, cdouble, clongdouble# + * * #otype = npy_float*4, npy_double*6, npy_half, npy_float, * npy_double, npy_longdouble, * npy_cfloat, npy_cdouble, npy_clongdouble# @@ -1066,8 +1069,7 @@ static PyObject * out1 = out = @one@; } else if (arg2 < 0) { - @name@_ctype_power(arg1, -arg2, &out); - out1 = (@otype@) (1.0 / out); + @oname@_ctype_power(arg1, arg2, &out1); } else { @name@_ctype_power(arg1, arg2, &out); diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py index 12b1a0fe3..75e91d247 100644 --- a/numpy/core/tests/test_scalarmath.py +++ b/numpy/core/tests/test_scalarmath.py @@ -122,6 +122,24 @@ class TestPower(TestCase): else: assert_almost_equal(b, 6765201, err_msg=msg) + def test_negative_power(self): + typelist = [np.int8, np.int16, np.int32, np.int64] + for t in typelist: + a = t(2) + b = t(-4) + result = a**b + msg = ("error with %r:" + "got %r, expected %r") % (t, result, 0.0625) + assert_(result == 0.0625, msg) + + c = t(4) + d = t(-15) + result = c**d + expected = 4.0**-15.0 + msg = ("error with %r:" + "got %r, expected %r") % (t, result, expected) + assert_almost_equal(result, expected, err_msg=msg) + def test_mixed_types(self): typelist = [np.int8, np.int16, np.float16, np.float32, np.float64, np.int8, |