Commits

Taavi Burns committed 90a692c

Fixing power (float and int) in numpypy

Comments (0)

Files changed (2)

pypy/module/micronumpy/test/test_ufuncs.py

         assert log1p(float('inf')) == float('inf')
         assert (log1p([0, 1e-50, math.e - 1]) == [0, 1e-50, 1]).all()
 
-    def test_power(self):
+    def test_power_float(self):
         import math
         from _numpypy import power, array
         a = array([1., 2., 3.])
         for i in range(len(a)):
             assert c[i] == a[i] ** b[i]
 
+        assert power(2, float('inf')) == float('inf')
+        assert power(float('inf'), float('inf')) == float('inf')
+        assert power(12345.0, 12345.0) == float('inf')
+        assert power(-12345.0, 12345.0) == float('-inf')
+        assert power(-12345.0, 12346.0) == float('inf')
+        assert math.isnan(power(-1, 1.1))
+        assert math.isnan(power(-1, -1.1))
+        assert power(-2.0, -1) == -0.5
+        assert power(-2.0, -2) == 0.25
+        assert power(12345.0, -12345.0) == 0
+        assert power(float('-inf'), 2) == float('inf')
+        assert power(float('-inf'), 2.5) == float('inf')
+        assert power(float('-inf'), 3) == float('-inf')
+
+    def test_power_int(self):
+        import math
+        from _numpypy import power, array
+        a = array([1, 2, 3])
+        b = power(a, 3)
+        for i in range(len(a)):
+            assert b[i] == a[i] ** 3
+
+        a = array([1, 2, 3])
+        b = array([1, 2, 3])
+        c = power(a, b)
+        for i in range(len(a)):
+            assert c[i] == a[i] ** b[i]
+
+        # assert power(12345, 12345) == -9223372036854775808
+        # assert power(-12345, 12345) == -9223372036854775808
+        # assert power(-12345, 12346) == -9223372036854775808
+        assert power(2, 0) == 1
+        assert power(2, -1) == 0
+        assert power(2, -2) == 0
+        assert power(-2, -1) == 0
+        assert power(-2, -2) == 0
+        assert power(12345, -12345) == 0
+
     def test_floordiv(self):
         from _numpypy import floor_divide, array
         a = array([1., 2., 3., 4., 5., 6., 6.01])

pypy/module/micronumpy/types.py

 
     @simple_binary_op
     def pow(self, v1, v2):
+        if v2 < 0:
+            return 0
         res = 1
         while v2 > 0:
             if v2 & 1:
 
     @simple_binary_op
     def pow(self, v1, v2):
-        return math.pow(v1, v2)
+        try:
+            return math.pow(v1, v2)
+        except ValueError:
+            return rfloat.NAN
+        except OverflowError:
+            if math.modf(v2)[0] == 0 and math.modf(v2 / 2)[0] != 0:
+                # Odd integer powers result in the same sign as the base
+                return rfloat.copysign(rfloat.INFINITY, v1)
+            return rfloat.INFINITY
 
     @simple_binary_op
     def copysign(self, v1, v2):