Author: Armin Rigo <[email protected]>
Branch:
Changeset: r67928:6eaf1ec3939a
Date: 2013-11-10 14:33 +0100
http://bitbucket.org/pypy/pypy/changeset/6eaf1ec3939a/
Log: Add a function to extract a (small) number of bits from a bigint.
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -943,6 +943,21 @@
return z
rshift._always_inline_ = 'try' # It's so fast that it's always benefitial.
+ def abs_rshift_and_mask(self, bigshiftcount, mask):
+ assert type(bigshiftcount) is r_ulonglong
+ assert mask >= 0
+ wordshift = bigshiftcount / SHIFT
+ numdigits = self.numdigits()
+ if wordshift >= numdigits:
+ return 0
+ wordshift = intmask(wordshift)
+ loshift = intmask(intmask(bigshiftcount) - intmask(wordshift * SHIFT))
+ lastdigit = self.digit(wordshift) >> loshift
+ if mask > (MASK >> loshift) and wordshift + 1 < numdigits:
+ hishift = SHIFT - loshift
+ lastdigit |= self.digit(wordshift+1) << hishift
+ return lastdigit & mask
+
@jit.elidable
def and_(self, other):
return _bitwise(self, '&', other)
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
@@ -475,6 +475,7 @@
def test_shift(self):
negative = -23
+ masks_list = [int((1 << i) - 1) for i in range(1, r_uint.BITS-1)]
for x in gen_signs([3L ** 30L, 5L ** 20L, 7 ** 300, 0L, 1L]):
f1 = rbigint.fromlong(x)
py.test.raises(ValueError, f1.lshift, negative)
@@ -484,7 +485,10 @@
res2 = f1.rshift(int(y)).tolong()
assert res1 == x << y
assert res2 == x >> y
-
+ for mask in masks_list:
+ res3 = f1.abs_rshift_and_mask(r_ulonglong(y), mask)
+ assert res3 == (abs(x) >> y) & mask
+
def test_bitwise(self):
for x in gen_signs([0, 1, 5, 11, 42, 43, 3 ** 30]):
for y in gen_signs([0, 1, 5, 11, 42, 43, 3 ** 30, 3 ** 31]):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit