Author: Brian Kearns <[email protected]>
Branch: 
Changeset: r67701:019951f063bd
Date: 2013-10-29 13:50 -0400
http://bitbucket.org/pypy/pypy/changeset/019951f063bd/

Log:    fix corner case of signed integer division overflow

diff --git a/pypy/module/micronumpy/test/test_numarray.py 
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1002,6 +1002,13 @@
         b = a // 2
         assert (b == [0, 0, 1, 1, 2]).all()
 
+    def test_signed_integer_division_overflow(self):
+        import numpypy as np
+        for s in (8, 16, 32, 64):
+            for o in ['__div__', '__floordiv__']:
+                a = np.array([-2**(s-1)], dtype='int%d' % s)
+                assert getattr(a, o)(-1) == 0
+
     def test_truediv(self):
         from operator import truediv
         from numpypy import arange
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -422,17 +422,29 @@
     def default_fromstring(self, space):
         return self.box(0)
 
-    @simple_binary_op
-    def div(self, v1, v2):
+    @specialize.argtype(1, 2)
+    def div(self, b1, b2):
+        v1 = self.for_computation(self.unbox(b1))
+        v2 = self.for_computation(self.unbox(b2))
         if v2 == 0:
-            return 0
-        return v1 / v2
+            return self.box(0)
+        if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is 
rffi.INT or
+                self.T is rffi.LONG or self.T is rffi.LONGLONG):
+            if v2 == -1 and v1 == 
self.for_computation(most_neg_value_of(self.T)):
+                return self.box(0)
+        return self.box(v1 / v2)
 
-    @simple_binary_op
-    def floordiv(self, v1, v2):
+    @specialize.argtype(1, 2)
+    def floordiv(self, b1, b2):
+        v1 = self.for_computation(self.unbox(b1))
+        v2 = self.for_computation(self.unbox(b2))
         if v2 == 0:
-            return 0
-        return v1 // v2
+            return self.box(0)
+        if (self.T is rffi.SIGNEDCHAR or self.T is rffi.SHORT or self.T is 
rffi.INT or
+                self.T is rffi.LONG or self.T is rffi.LONGLONG):
+            if v2 == -1 and v1 == 
self.for_computation(most_neg_value_of(self.T)):
+                return self.box(0)
+        return self.box(v1 // v2)
 
     @simple_binary_op
     def mod(self, v1, v2):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to