[pypy-commit] pypy improve-rbigint: Revert changes to rshift, and change a test so it fails, and fix it. All tests should now pass
Stian Andreassen
noreply at buildbot.pypy.org
Thu Aug 23 06:16:21 CEST 2012
Author: Stian Andreassen
Branch: improve-rbigint
Changeset: r56815:31d713444087
Date: 2012-08-23 06:15 +0200
http://bitbucket.org/pypy/pypy/changeset/31d713444087/
Log: Revert changes to rshift, and change a test so it fails, and fix it.
All tests should now pass
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -21,7 +21,6 @@
#SHIFT = (LONG_BIT // 2) - 1
if SUPPORT_INT128:
SHIFT = 63
- BASE = long(1 << SHIFT)
UDIGIT_TYPE = r_ulonglong
if LONG_BIT >= 64:
UDIGIT_MASK = intmask
@@ -36,14 +35,13 @@
UNSIGNED_TYPE = rffi.ULONGLONG
else:
SHIFT = 31
- BASE = int(1 << SHIFT)
UDIGIT_TYPE = r_uint
UDIGIT_MASK = intmask
STORE_TYPE = lltype.Signed
UNSIGNED_TYPE = lltype.Unsigned
LONG_TYPE = rffi.LONGLONG
-MASK = BASE - 1
+MASK = int((1 << SHIFT) - 1)
FLOAT_MULTIPLIER = float(1 << SHIFT)
# Debugging digit array access.
@@ -762,27 +760,24 @@
elif int_other == 0:
return self
if self.sign == -1 and not dont_invert:
- a1 = self.invert()
- a2 = a1.rshift(int_other)
- return a2.invert()
+ a = self.invert().rshift(int_other)
+ return a.invert()
- wordshift = int_other // SHIFT
+ wordshift = int_other / SHIFT
newsize = self.numdigits() - wordshift
if newsize <= 0:
return NULLRBIGINT
loshift = int_other % SHIFT
hishift = SHIFT - loshift
- # Not 100% sure here, but the reason why it won't be a problem is because
- # int is max 63bit, same as our SHIFT now.
- #lomask = UDIGIT_MASK((UDIGIT_TYPE(1) << hishift) - 1)
- #himask = MASK ^ lomask
+ lomask = (1 << hishift) - 1
+ himask = MASK ^ lomask
z = rbigint([NULLDIGIT] * newsize, self.sign, newsize)
i = 0
while i < newsize:
- newdigit = (self.udigit(wordshift) >> loshift) #& lomask
+ newdigit = (self.digit(wordshift) >> loshift) & lomask
if i+1 < newsize:
- newdigit += (self.udigit(wordshift+1) << hishift) #& himask
+ newdigit |= (self.digit(wordshift+1) << hishift) & himask
z.setdigit(i, newdigit)
i += 1
wordshift += 1
@@ -1408,7 +1403,6 @@
if not size:
size = pin.numdigits()
size -= 1
-
while size >= 0:
rem = (rem << SHIFT) | pin.widedigit(size)
hi = rem // n
@@ -1438,7 +1432,7 @@
x[m-1], and the remaining carry (0 or 1) is returned.
Python adaptation: x is addressed relative to xofs!
"""
- carry = r_uint(0)
+ carry = UDIGIT_TYPE(0)
assert m >= n
i = _load_unsigned_digit(xofs)
@@ -1463,7 +1457,7 @@
far as x[m-1], and the remaining borrow (0 or 1) is returned.
Python adaptation: x is addressed relative to xofs!
"""
- borrow = r_uint(0)
+ borrow = UDIGIT_TYPE(0)
assert m >= n
i = _load_unsigned_digit(xofs)
@@ -1559,13 +1553,17 @@
""" Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has
at most (and usually exactly) k = size_v - size_w digits. """
k = size_v - size_w
+ if k == 0:
+ return NULLRBIGINT, v1
+
assert k > 0
a = rbigint([NULLDIGIT] * k, 1, k)
- wm1 = w.digit(abs(size_w-1))
+ wm1 = w.widedigit(abs(size_w-1))
wm2 = w.widedigit(abs(size_w-2))
- j = size_v
+ j = size_v - 1
+ k -= 1
while k >= 0:
assert j >= 0
""" inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving
@@ -1575,17 +1573,15 @@
if j >= size_v:
vtop = 0
else:
- vtop = v.digit(j)
+ vtop = v.widedigit(j)
assert vtop <= wm1
vv = (vtop << SHIFT) | v.widedigit(abs(j-1))
- q = UDIGIT_MASK(vv / wm1)
+ q = vv / wm1
r = vv - wm1 * q
while wm2 * q > ((r << SHIFT) | v.widedigit(abs(j-2))):
q -= 1
r += wm1
- if r > MASK:
- break
-
+
assert q < MASK
# subtract q*w0[0:size_w] from vk[0:size_w+1]
@@ -1609,9 +1605,10 @@
q -= 1
# store quotient digit
+ a.setdigit(k, q)
k -= 1
j -= 1
- a.setdigit(k, q)
+
carry = _v_rshift(w, v, size_w, d)
assert carry == 0
diff --git a/pypy/rlib/test/test_rbigint.py b/pypy/rlib/test/test_rbigint.py
--- a/pypy/rlib/test/test_rbigint.py
+++ b/pypy/rlib/test/test_rbigint.py
@@ -547,7 +547,7 @@
Rx = 1 << 130
Rx2 = 1 << 150
Ry = 1 << 127
- Ry2 = 1<< 130
+ Ry2 = 1<< 150
for i in range(10):
x = long(randint(Rx, Rx2))
y = long(randint(Ry, Ry2))
More information about the pypy-commit
mailing list