Author: stian
Branch: bigint-with-int-ops
Changeset: r66023:3d921becf5f9
Date: 2013-08-08 21:26 +0200
http://bitbucket.org/pypy/pypy/changeset/3d921becf5f9/

Log:    Support mul ops

diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -204,6 +204,9 @@
 def mul__Long_Long(space, w_long1, w_long2):
     return W_LongObject(w_long1.num.mul(w_long2.num))
 
+def mul__Long_Int(space, w_long1, w_int2):
+    return W_LongObject(w_long1.num.int_mul(w_int2.intval))
+
 def truediv__Long_Long(space, w_long1, w_long2):
     try:
         f = w_long1.num.truediv(w_long2.num)
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -661,6 +661,37 @@
         return result
 
     @jit.elidable
+    def int_mul(self, b):
+        if not int_in_valid_range(b):
+            # Fallback to long.
+            return self.mul(rbigint.fromint(b))
+
+        asize = self.numdigits()
+        digit = abs(b)
+        bsign = -1 if b < 0 else 1
+
+        if self.sign == 0 or b == 0:
+            return NULLRBIGINT
+
+        if digit == 1:
+            return rbigint(self._digits[:self.size], self.sign * bsign, asize)
+        elif asize == 1:
+            res = self.widedigit(0) * digit
+            carry = res >> SHIFT
+            if carry:
+                return rbigint([_store_digit(res & MASK), 
_store_digit(carry)], self.sign * bsign, 2)
+            else:
+                return rbigint([_store_digit(res & MASK)], self.sign * bsign, 
1)
+
+        elif digit & (digit - 1) == 0:
+            result = self.lqshift(ptwotable[digit])
+        else:
+            result = _muladd1(self, digit)
+
+        result.sign = self.sign * bsign
+        return result
+
+    @jit.elidable
     def truediv(self, other):
         div = _bigint_true_divide(self, other)
         return div
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
@@ -282,6 +282,17 @@
         result = f1.mul(f1)
         assert result.tolong() == x * x
 
+    def test_int_mul(self):
+        x = -1238585838347L
+        y = 3
+        for i in [-1, 1]:
+            for j in [-1, 1]:
+                f1 = rbigint.fromlong(x * i)
+                f2 = y * j
+                result = f1.int_mul(f2)
+                assert result.tolong() == (x * i) * (y * j)
+                
+
     def test_tofloat(self):
         x = 12345678901234567890L ** 10
         f1 = rbigint.fromlong(x)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to