[pypy-commit] pypy math-improvements: Revert the inplace invert from rshift as it may break things

Stian Andreassen pypy.commits at gmail.com
Fri Dec 14 22:00:24 EST 2018


Author: Stian Andreassen
Branch: math-improvements
Changeset: r95497:fc1d97a72983
Date: 2018-12-15 03:56 +0100
http://bitbucket.org/pypy/pypy/changeset/fc1d97a72983/

Log:	Revert the inplace invert from rshift as it may break things

diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -1231,43 +1231,30 @@
             raise ValueError("negative shift count")
         elif int_other == 0:
             return self
-        invert = False
         if self.sign == -1 and not dont_invert:
-            first = self.digit(0)
-            if first == 0:
-                a = self.invert().rshift(int_other)
-                return a.invert()
-            invert = True
+            a = self.invert().rshift(int_other)
+            return a.invert()
 
         wordshift = int_other / SHIFT
-        loshift = int_other % SHIFT
         newsize = self.numdigits() - wordshift
         if newsize <= 0:
-            if invert:
-                return ONENEGATIVERBIGINT
-            else:
-                return NULLRBIGINT
-
-
+            return NULLRBIGINT
+
+        loshift = int_other % SHIFT
         hishift = SHIFT - loshift
         z = rbigint([NULLDIGIT] * newsize, self.sign, newsize)
         i = 0
         while i < newsize:
-            digit = self.udigit(wordshift)
-            if i == 0 and invert and wordshift == 0:
-                digit -= 1
-            newdigit = (digit >> loshift)
+            newdigit = (self.digit(wordshift) >> loshift)
             if i+1 < newsize:
-                newdigit |= (self.udigit(wordshift+1) << hishift)
+                newdigit |= (self.digit(wordshift+1) << hishift)
             z.setdigit(i, newdigit)
             i += 1
             wordshift += 1
-        if invert:
-            z.setdigit(0, z.digit(0)+1)
         z._normalize()
         return z
-    rshift._always_inline_ = 'try' # It's so fast that it's always beneficial.
-
+    rshift._always_inline_ = 'try' # It's so fast that it's always benefitial.
+    
     @jit.elidable
     def rqshift(self, int_other):
         wordshift = int_other / SHIFT
diff --git a/rpython/rlib/test/test_rbigint.py b/rpython/rlib/test/test_rbigint.py
--- a/rpython/rlib/test/test_rbigint.py
+++ b/rpython/rlib/test/test_rbigint.py
@@ -652,6 +652,9 @@
         # test special optimization case in rshift:
         assert rbigint.fromlong(-(1 << 100)).rshift(5).tolong() == -(1 << 100) >> 5
 
+        # Chek value accuracy.
+        assert rbigint.fromlong(18446744073709551615L).rshift(1).tolong() == 18446744073709551615L >> 1
+
     def test_qshift(self):
         for x in range(10):
             for y in range(1, 161, 16):


More information about the pypy-commit mailing list