summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Moore <ewm@redtetrahedron.org>2016-03-22 08:53:43 -0400
committerEric Moore <ewm@redtetrahedron.org>2016-03-22 08:53:43 -0400
commit58ff38a547e59e2e8f8278d445f66c1091f1299a (patch)
tree8ecfedf8d1b2b7660ae460eb94306e27669d64f0
parent5c24db244ec8a8d7e4ca2f823b0ba71b7d4dff3d (diff)
downloadpython-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.src6
-rw-r--r--numpy/core/tests/test_scalarmath.py18
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,