[pypy-commit] pypy default: Merge heads
amauryfa
noreply at buildbot.pypy.org
Sat Jul 21 20:32:47 CEST 2012
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r56379:47b1bf0dc0d8
Date: 2012-07-21 20:32 +0200
http://bitbucket.org/pypy/pypy/changeset/47b1bf0dc0d8/
Log: Merge heads
diff --git a/pypy/module/sys/system.py b/pypy/module/sys/system.py
--- a/pypy/module/sys/system.py
+++ b/pypy/module/sys/system.py
@@ -47,8 +47,8 @@
return space.call_function(w_float_info, space.newtuple(info_w))
def get_long_info(space):
- #assert rbigint.SHIFT == 31
- bits_per_digit = 31 #rbigint.SHIFT
+ assert rbigint.SHIFT == 31
+ bits_per_digit = rbigint.SHIFT
sizeof_digit = rffi.sizeof(rffi.ULONG)
info_w = [
space.wrap(bits_per_digit),
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -87,10 +87,6 @@
LONG_BIT_SHIFT += 1
assert LONG_BIT_SHIFT < 99, "LONG_BIT_SHIFT value not found?"
-LONGLONGLONG_BIT = 128
-LONGLONGLONG_MASK = (2**LONGLONGLONG_BIT)-1
-LONGLONGLONG_TEST = 2**(LONGLONGLONG_BIT-1)
-
"""
int is no longer necessarily the same size as the target int.
We therefore can no longer use the int type as it is, but need
@@ -115,26 +111,16 @@
n -= 2*LONG_TEST
return int(n)
-if LONG_BIT >= 64:
- def longlongmask(n):
- assert isinstance(n, (int, long))
- return int(n)
-else:
- def longlongmask(n):
- """
- NOT_RPYTHON
- """
- assert isinstance(n, (int, long))
- n = long(n)
- n &= LONGLONG_MASK
- if n >= LONGLONG_TEST:
- n -= 2*LONGLONG_TEST
- return r_longlong(n)
-
-def longlonglongmask(n):
- # Assume longlonglong doesn't overflow. This is perfectly fine for rbigint.
- # We deal directly with overflow there anyway.
- return r_longlonglong(n)
+def longlongmask(n):
+ """
+ NOT_RPYTHON
+ """
+ assert isinstance(n, (int, long))
+ n = long(n)
+ n &= LONGLONG_MASK
+ if n >= LONGLONG_TEST:
+ n -= 2*LONGLONG_TEST
+ return r_longlong(n)
def widen(n):
from pypy.rpython.lltypesystem import lltype
@@ -489,7 +475,6 @@
r_longlong = build_int('r_longlong', True, 64)
r_ulonglong = build_int('r_ulonglong', False, 64)
-r_longlonglong = build_int('r_longlonglong', True, 128)
longlongmax = r_longlong(LONGLONG_TEST - 1)
if r_longlong is not r_int:
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -1,4 +1,4 @@
-from pypy.rlib.rarithmetic import LONG_BIT, intmask, longlongmask, r_uint, r_ulonglong, r_longlonglong
+from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int
from pypy.rlib.rarithmetic import most_neg_value_of_same_type
from pypy.rlib.rfloat import isfinite
@@ -7,41 +7,19 @@
from pypy.rlib import jit
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython import extregistry
-from pypy.rpython.tool import rffi_platform
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
import math, sys
-SUPPORT_INT128 = rffi_platform.has('__int128', '')
-
# note about digit sizes:
# In division, the native integer type must be able to hold
# a sign bit plus two digits plus 1 overflow bit.
#SHIFT = (LONG_BIT // 2) - 1
-if SUPPORT_INT128:
- SHIFT = 63
- BASE = long(1 << SHIFT)
- UDIGIT_TYPE = r_ulonglong
- UDIGIT_MASK = longlongmask
- LONG_TYPE = rffi.__INT128
- if LONG_BIT > SHIFT:
- STORE_TYPE = lltype.Signed
- UNSIGNED_TYPE = lltype.Unsigned
- else:
- STORE_TYPE = rffi.LONGLONG
- 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
+SHIFT = 31
-MASK = BASE - 1
-FLOAT_MULTIPLIER = float(1 << LONG_BIT) # Because it works.
+MASK = int((1 << SHIFT) - 1)
+FLOAT_MULTIPLIER = float(1 << SHIFT)
+
# Debugging digit array access.
#
@@ -53,19 +31,10 @@
# both operands contain more than KARATSUBA_CUTOFF digits (this
# being an internal Python long digit, in base BASE).
-# Karatsuba is O(N**1.585)
USE_KARATSUBA = True # set to False for comparison
-
-if SHIFT > 31:
- KARATSUBA_CUTOFF = 19
-else:
- KARATSUBA_CUTOFF = 38
-
+KARATSUBA_CUTOFF = 70
KARATSUBA_SQUARE_CUTOFF = 2 * KARATSUBA_CUTOFF
-USE_TOOMCOCK = False
-TOOMCOOK_CUTOFF = 10000 # Smallest possible cutoff is 3. Ideal is probably around 150+
-
# For exponentiation, use the binary left-to-right algorithm
# unless the exponent contains more than FIVEARY_CUTOFF digits.
# In that case, do 5 bits at a time. The potential drawback is that
@@ -75,20 +44,31 @@
def _mask_digit(x):
- return UDIGIT_MASK(x & MASK)
+ return intmask(x & MASK)
_mask_digit._annspecialcase_ = 'specialize:argtype(0)'
def _widen_digit(x):
- return rffi.cast(LONG_TYPE, x)
+ if not we_are_translated():
+ assert is_valid_int(x), "widen_digit() takes an int, got a %r" % type(x)
+ if SHIFT <= 15:
+ return int(x)
+ return r_longlong(x)
def _store_digit(x):
- return rffi.cast(STORE_TYPE, x)
-_store_digit._annspecialcase_ = 'specialize:argtype(0)'
+ if not we_are_translated():
+ assert is_valid_int(x), "store_digit() takes an int, got a %r" % type(x)
+ if SHIFT <= 15:
+ return rffi.cast(rffi.SHORT, x)
+ elif SHIFT <= 31:
+ return rffi.cast(rffi.INT, x)
+ else:
+ raise ValueError("SHIFT too large!")
+
+def _load_digit(x):
+ return rffi.cast(lltype.Signed, x)
def _load_unsigned_digit(x):
- return rffi.cast(UNSIGNED_TYPE, x)
-
-_load_unsigned_digit._always_inline_ = True
+ return rffi.cast(lltype.Unsigned, x)
NULLDIGIT = _store_digit(0)
ONEDIGIT = _store_digit(1)
@@ -96,8 +76,7 @@
def _check_digits(l):
for x in l:
assert type(x) is type(NULLDIGIT)
- assert UDIGIT_MASK(x) & MASK == UDIGIT_MASK(x)
-
+ assert intmask(x) & MASK == intmask(x)
class Entry(extregistry.ExtRegistryEntry):
_about_ = _check_digits
def compute_result_annotation(self, s_list):
@@ -108,52 +87,46 @@
def specialize_call(self, hop):
hop.exception_cannot_occur()
+
class rbigint(object):
"""This is a reimplementation of longs using a list of digits."""
- def __init__(self, digits=[NULLDIGIT], sign=0, size=0):
- if not we_are_translated():
- _check_digits(digits)
+ def __init__(self, digits=[], sign=0):
+ if len(digits) == 0:
+ digits = [NULLDIGIT]
+ _check_digits(digits)
make_sure_not_resized(digits)
self._digits = digits
- assert size >= 0
- self.size = size or len(digits)
self.sign = sign
def digit(self, x):
"""Return the x'th digit, as an int."""
- return self._digits[x]
- digit._always_inline_ = True
+ return _load_digit(self._digits[x])
def widedigit(self, x):
"""Return the x'th digit, as a long long int if needed
to have enough room to contain two digits."""
- return _widen_digit(self._digits[x])
- widedigit._always_inline_ = True
+ return _widen_digit(_load_digit(self._digits[x]))
def udigit(self, x):
"""Return the x'th digit, as an unsigned int."""
return _load_unsigned_digit(self._digits[x])
- udigit._always_inline_ = True
def setdigit(self, x, val):
- val = val & MASK
+ val = _mask_digit(val)
assert val >= 0
self._digits[x] = _store_digit(val)
setdigit._annspecialcase_ = 'specialize:argtype(2)'
- setdigit._always_inline_ = True
def numdigits(self):
- return self.size
- numdigits._always_inline_ = True
-
+ return len(self._digits)
+
@staticmethod
@jit.elidable
def fromint(intval):
# This function is marked as pure, so you must not call it and
# then modify the result.
check_regular_int(intval)
-
if intval < 0:
sign = -1
ival = r_uint(-intval)
@@ -161,42 +134,33 @@
sign = 1
ival = r_uint(intval)
else:
- return NULLRBIGINT
+ return rbigint()
# Count the number of Python digits.
# We used to pick 5 ("big enough for anything"), but that's a
# waste of time and space given that 5*15 = 75 bits are rarely
# needed.
- # XXX: Even better!
- if SHIFT >= 63:
- carry = ival >> SHIFT
- if carry:
- return rbigint([_store_digit(ival & MASK),
- _store_digit(carry & MASK)], sign, 2)
- else:
- return rbigint([_store_digit(ival & MASK)], sign, 1)
-
t = ival
ndigits = 0
while t:
ndigits += 1
t >>= SHIFT
- v = rbigint([NULLDIGIT] * ndigits, sign, ndigits)
+ v = rbigint([NULLDIGIT] * ndigits, sign)
t = ival
p = 0
while t:
v.setdigit(p, t)
t >>= SHIFT
p += 1
-
return v
@staticmethod
+ @jit.elidable
def frombool(b):
# This function is marked as pure, so you must not call it and
# then modify the result.
if b:
- return ONERBIGINT
- return NULLRBIGINT
+ return rbigint([ONEDIGIT], 1)
+ return rbigint()
@staticmethod
def fromlong(l):
@@ -204,7 +168,6 @@
return rbigint(*args_from_long(l))
@staticmethod
- @jit.elidable
def fromfloat(dval):
""" Create a new bigint object from a float """
# This function is not marked as pure because it can raise
@@ -222,9 +185,9 @@
dval = -dval
frac, expo = math.frexp(dval) # dval = frac*2**expo; 0.0 <= frac < 1.0
if expo <= 0:
- return NULLRBIGINT
+ return rbigint()
ndig = (expo-1) // SHIFT + 1 # Number of 'digits' in result
- v = rbigint([NULLDIGIT] * ndig, sign, ndig)
+ v = rbigint([NULLDIGIT] * ndig, sign)
frac = math.ldexp(frac, (expo-1) % SHIFT + 1)
for i in range(ndig-1, -1, -1):
# use int(int(frac)) as a workaround for a CPython bug:
@@ -266,7 +229,6 @@
raise OverflowError
return intmask(intmask(x) * sign)
- @jit.elidable
def tolonglong(self):
return _AsLongLong(self)
@@ -278,7 +240,6 @@
raise ValueError("cannot convert negative integer to unsigned int")
return self._touint_helper()
- @jit.elidable
def _touint_helper(self):
x = r_uint(0)
i = self.numdigits() - 1
@@ -287,11 +248,10 @@
x = (x << SHIFT) + self.udigit(i)
if (x >> SHIFT) != prev:
raise OverflowError(
- "long int too large to convert to unsigned int (%d, %d)" % (x >> SHIFT, prev))
+ "long int too large to convert to unsigned int")
i -= 1
return x
- @jit.elidable
def toulonglong(self):
if self.sign == -1:
raise ValueError("cannot convert negative integer to unsigned int")
@@ -307,21 +267,17 @@
def tofloat(self):
return _AsDouble(self)
- @jit.elidable
def format(self, digits, prefix='', suffix=''):
# 'digits' is a string whose length is the base to use,
# and where each character is the corresponding digit.
return _format(self, digits, prefix, suffix)
- @jit.elidable
def repr(self):
return _format(self, BASE10, '', 'L')
- @jit.elidable
def str(self):
return _format(self, BASE10)
- @jit.elidable
def eq(self, other):
if (self.sign != other.sign or
self.numdigits() != other.numdigits()):
@@ -381,11 +337,9 @@
def ge(self, other):
return not self.lt(other)
- @jit.elidable
def hash(self):
return _hash(self)
- @jit.elidable
def add(self, other):
if self.sign == 0:
return other
@@ -398,131 +352,42 @@
result.sign *= other.sign
return result
- @jit.elidable
def sub(self, other):
if other.sign == 0:
return self
if self.sign == 0:
- return rbigint(other._digits[:], -other.sign, other.size)
+ return rbigint(other._digits[:], -other.sign)
if self.sign == other.sign:
result = _x_sub(self, other)
else:
result = _x_add(self, other)
result.sign *= self.sign
+ result._normalize()
return result
- @jit.elidable
- def mul(self, b):
- asize = self.numdigits()
- bsize = b.numdigits()
-
- a = self
-
- if asize > bsize:
- a, b, asize, bsize = b, a, bsize, asize
-
- if a.sign == 0 or b.sign == 0:
- return NULLRBIGINT
-
- if asize == 1:
- if a._digits[0] == NULLDIGIT:
- return NULLRBIGINT
- elif a._digits[0] == ONEDIGIT:
- return rbigint(b._digits[:], a.sign * b.sign, b.size)
- elif bsize == 1:
- res = b.widedigit(0) * a.widedigit(0)
- carry = res >> SHIFT
- if carry:
- return rbigint([_store_digit(res & MASK), _store_digit(carry & MASK)], a.sign * b.sign, 2)
- else:
- return rbigint([_store_digit(res & MASK)], a.sign * b.sign, 1)
-
- result = _x_mul(a, b, a.digit(0))
- elif USE_TOOMCOCK and asize >= TOOMCOOK_CUTOFF:
- result = _tc_mul(a, b)
- elif USE_KARATSUBA:
- if a is b:
- i = KARATSUBA_SQUARE_CUTOFF
- else:
- i = KARATSUBA_CUTOFF
-
- if asize <= i:
- result = _x_mul(a, b)
- elif 2 * asize <= bsize:
- result = _k_lopsided_mul(a, b)
- else:
- result = _k_mul(a, b)
+ def mul(self, other):
+ if USE_KARATSUBA:
+ result = _k_mul(self, other)
else:
- result = _x_mul(a, b)
-
- result.sign = a.sign * b.sign
+ result = _x_mul(self, other)
+ result.sign = self.sign * other.sign
return result
- @jit.elidable
def truediv(self, other):
div = _bigint_true_divide(self, other)
return div
- @jit.elidable
def floordiv(self, other):
- if other.numdigits() == 1 and other.sign == 1:
- digit = other.digit(0)
- if digit == 1:
- return rbigint(self._digits[:], other.sign * self.sign, self.size)
- elif digit and digit & (digit - 1) == 0:
- return self.rshift(ptwotable[digit])
-
- div, mod = _divrem(self, other)
- if mod.sign * other.sign == -1:
- if div.sign == 0:
- return ONENEGATIVERBIGINT
- if div.sign == 1:
- _v_isub(div, 0, div.numdigits(), ONERBIGINT, 1)
- else:
- _v_iadd(div, 0, div.numdigits(), ONERBIGINT, 1)
+ div, mod = self.divmod(other)
return div
def div(self, other):
return self.floordiv(other)
- @jit.elidable
def mod(self, other):
- if self.sign == 0:
- return NULLRBIGINT
-
- if other.sign != 0 and other.numdigits() == 1:
- digit = other.digit(0)
- if digit == 1:
- return NULLRBIGINT
- elif digit == 2:
- modm = self.digit(0) % digit
- if modm:
- return ONENEGATIVERBIGINT if other.sign == -1 else ONERBIGINT
- return NULLRBIGINT
- elif digit & (digit - 1) == 0:
- mod = self.and_(rbigint([_store_digit(digit - 1)], 1, 1))
- else:
- # Perform
- size = self.numdigits() - 1
- if size > 0:
- rem = self.widedigit(size)
- size -= 1
- while size >= 0:
- rem = ((rem << SHIFT) + self.widedigit(size)) % digit
- size -= 1
- else:
- rem = self.digit(0) % digit
-
- if rem == 0:
- return NULLRBIGINT
- mod = rbigint([_store_digit(rem)], -1 if self.sign < 0 else 1, 1)
- else:
- div, mod = _divrem(self, other)
- if mod.sign * other.sign == -1:
- mod = mod.add(other)
+ div, mod = self.divmod(other)
return mod
- @jit.elidable
def divmod(v, w):
"""
The / and % operators are now defined in terms of divmod().
@@ -543,15 +408,9 @@
div, mod = _divrem(v, w)
if mod.sign * w.sign == -1:
mod = mod.add(w)
- if div.sign == 0:
- return ONENEGATIVERBIGINT, mod
- if div.sign == 1:
- _v_isub(div, 0, div.numdigits(), ONERBIGINT, 1)
- else:
- _v_iadd(div, 0, div.numdigits(), ONERBIGINT, 1)
+ div = div.sub(rbigint([_store_digit(1)], 1))
return div, mod
- @jit.elidable
def pow(a, b, c=None):
negativeOutput = False # if x<0 return negative output
@@ -566,14 +425,7 @@
"cannot be negative when 3rd argument specified")
# XXX failed to implement
raise ValueError("bigint pow() too negative")
-
- if b.sign == 0:
- return ONERBIGINT
- elif a.sign == 0:
- return NULLRBIGINT
-
- size_b = b.numdigits()
-
+
if c is not None:
if c.sign == 0:
raise ValueError("pow() 3rd argument cannot be 0")
@@ -587,55 +439,36 @@
# if modulus == 1:
# return 0
- if c.numdigits() == 1 and c._digits[0] == ONEDIGIT:
- return NULLRBIGINT
+ if c.numdigits() == 1 and c.digit(0) == 1:
+ return rbigint()
# if base < 0:
# base = base % modulus
# Having the base positive just makes things easier.
if a.sign < 0:
- a = a.mod(c)
-
-
- elif size_b == 1:
- if b._digits[0] == NULLDIGIT:
- return ONERBIGINT if a.sign == 1 else ONENEGATIVERBIGINT
- elif b._digits[0] == ONEDIGIT:
- return a
- elif a.numdigits() == 1:
- adigit = a.digit(0)
- digit = b.digit(0)
- if adigit == 1:
- if a.sign == -1 and digit % 2:
- return ONENEGATIVERBIGINT
- return ONERBIGINT
- elif adigit & (adigit - 1) == 0:
- ret = a.lshift(((digit-1)*(ptwotable[adigit]-1)) + digit-1)
- if a.sign == -1 and not digit % 2:
- ret.sign = 1
- return ret
-
+ a, temp = a.divmod(c)
+ a = temp
+
# At this point a, b, and c are guaranteed non-negative UNLESS
# c is NULL, in which case a may be negative. */
- z = rbigint([ONEDIGIT], 1, 1)
-
+ z = rbigint([_store_digit(1)], 1)
+
# python adaptation: moved macros REDUCE(X) and MULT(X, Y, result)
# into helper function result = _help_mult(x, y, c)
- if size_b <= FIVEARY_CUTOFF:
+ if b.numdigits() <= FIVEARY_CUTOFF:
# Left-to-right binary exponentiation (HAC Algorithm 14.79)
# http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
- size_b -= 1
- while size_b >= 0:
- bi = b.digit(size_b)
+ i = b.numdigits() - 1
+ while i >= 0:
+ bi = b.digit(i)
j = 1 << (SHIFT-1)
while j != 0:
z = _help_mult(z, z, c)
if bi & j:
z = _help_mult(z, a, c)
j >>= 1
- size_b -= 1
-
+ i -= 1
else:
# Left-to-right 5-ary exponentiation (HAC Algorithm 14.82)
# This is only useful in the case where c != None.
@@ -644,7 +477,7 @@
table[0] = z
for i in range(1, 32):
table[i] = _help_mult(table[i-1], a, c)
-
+ i = b.numdigits()
# Note that here SHIFT is not a multiple of 5. The difficulty
# is to extract 5 bits at a time from 'b', starting from the
# most significant digits, so that at the end of the algorithm
@@ -653,11 +486,11 @@
# m+ = m rounded up to the next multiple of 5
# j = (m+) % SHIFT = (m+) - (i * SHIFT)
# (computed without doing "i * SHIFT", which might overflow)
- j = size_b % 5
+ j = i % 5
if j != 0:
j = 5 - j
if not we_are_translated():
- assert j == (size_b*SHIFT+4)//5*5 - size_b*SHIFT
+ assert j == (i*SHIFT+4)//5*5 - i*SHIFT
#
accum = r_uint(0)
while True:
@@ -667,12 +500,10 @@
else:
# 'accum' does not have enough digit.
# must get the next digit from 'b' in order to complete
- if size_b == 0:
- break # Done
-
- size_b -= 1
- assert size_b >= 0
- bi = b.udigit(size_b)
+ i -= 1
+ if i < 0:
+ break # done
+ bi = b.udigit(i)
index = ((accum << (-j)) | (bi >> (j+SHIFT))) & 0x1f
accum = bi
j += SHIFT
@@ -683,38 +514,20 @@
z = _help_mult(z, table[index], c)
#
assert j == -5
-
+
if negativeOutput and z.sign != 0:
z = z.sub(c)
return z
def neg(self):
- return rbigint(self._digits[:], -self.sign, self.size)
+ return rbigint(self._digits, -self.sign)
def abs(self):
- if self.sign != -1:
- return self
- return rbigint(self._digits[:], abs(self.sign), self.size)
+ return rbigint(self._digits, abs(self.sign))
def invert(self): #Implement ~x as -(x + 1)
- if self.sign == 0:
- return ONENEGATIVERBIGINT
-
- ret = self.add(ONERBIGINT)
- ret.sign = -ret.sign
- return ret
+ return self.add(rbigint([_store_digit(1)], 1)).neg()
- def inplace_invert(self): # Used by rshift and bitwise to prevent a double allocation.
- if self.sign == 0:
- return ONENEGATIVERBIGINT
- if self.sign == 1:
- _v_iadd(self, 0, self.numdigits(), ONERBIGINT, 1)
- else:
- _v_isub(self, 0, self.numdigits(), ONERBIGINT, 1)
- self.sign = -self.sign
- return self
-
- @jit.elidable
def lshift(self, int_other):
if int_other < 0:
raise ValueError("negative shift count")
@@ -725,50 +538,27 @@
wordshift = int_other // SHIFT
remshift = int_other - wordshift * SHIFT
- if not remshift:
- return rbigint([NULLDIGIT] * wordshift + self._digits, self.sign, self.size + wordshift)
-
oldsize = self.numdigits()
- newsize = oldsize + wordshift + 1
- z = rbigint([NULLDIGIT] * newsize, self.sign, newsize)
+ newsize = oldsize + wordshift
+ if remshift:
+ newsize += 1
+ z = rbigint([NULLDIGIT] * newsize, self.sign)
accum = _widen_digit(0)
+ i = wordshift
j = 0
while j < oldsize:
- accum += self.widedigit(j) << remshift
- z.setdigit(wordshift, accum)
+ accum |= self.widedigit(j) << remshift
+ z.setdigit(i, accum)
accum >>= SHIFT
- wordshift += 1
+ i += 1
j += 1
-
- newsize -= 1
- assert newsize >= 0
- z.setdigit(newsize, accum)
-
+ if remshift:
+ z.setdigit(newsize - 1, accum)
+ else:
+ assert not accum
z._normalize()
return z
- lshift._always_inline_ = True # It's so fast that it's always benefitial.
-
- @jit.elidable
- def lqshift(self, int_other):
- " A quicker one with much less checks, int_other is valid and for the most part constant."
- assert int_other > 0
- oldsize = self.numdigits()
-
- z = rbigint([NULLDIGIT] * (oldsize + 1), self.sign, (oldsize + 1))
- accum = _widen_digit(0)
-
- for i in range(oldsize):
- accum += self.widedigit(i) << int_other
- z.setdigit(i, accum)
- accum >>= SHIFT
-
- z.setdigit(oldsize, accum)
- z._normalize()
- return z
- lqshift._always_inline_ = True # It's so fast that it's always benefitial.
-
- @jit.elidable
def rshift(self, int_other, dont_invert=False):
if int_other < 0:
raise ValueError("negative shift count")
@@ -777,41 +567,36 @@
if self.sign == -1 and not dont_invert:
a1 = self.invert()
a2 = a1.rshift(int_other)
- return a2.inplace_invert()
+ return a2.invert()
wordshift = int_other // SHIFT
newsize = self.numdigits() - wordshift
if newsize <= 0:
- return NULLRBIGINT
+ return rbigint()
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
- z = rbigint([NULLDIGIT] * newsize, self.sign, newsize)
+ lomask = intmask((r_uint(1) << hishift) - 1)
+ himask = MASK ^ lomask
+ z = rbigint([NULLDIGIT] * newsize, self.sign)
i = 0
+ j = wordshift
while i < newsize:
- newdigit = (self.udigit(wordshift) >> loshift) #& lomask
+ newdigit = (self.digit(j) >> loshift) & lomask
if i+1 < newsize:
- newdigit += (self.udigit(wordshift+1) << hishift) #& himask
+ newdigit |= intmask(self.digit(j+1) << hishift) & himask
z.setdigit(i, newdigit)
i += 1
- wordshift += 1
+ j += 1
z._normalize()
return z
- rshift._always_inline_ = True # It's so fast that it's always benefitial.
-
- @jit.elidable
+
def and_(self, other):
return _bitwise(self, '&', other)
- @jit.elidable
def xor(self, other):
return _bitwise(self, '^', other)
- @jit.elidable
def or_(self, other):
return _bitwise(self, '|', other)
@@ -824,7 +609,6 @@
def hex(self):
return _format(self, BASE16, '0x', 'L')
- @jit.elidable
def log(self, base):
# base is supposed to be positive or 0.0, which means we use e
if base == 10.0:
@@ -845,23 +629,22 @@
return l * self.sign
def _normalize(self):
- i = self.numdigits()
- # i is always >= 1
- while i > 1 and self._digits[i - 1] == NULLDIGIT:
- i -= 1
- assert i > 0
- if i != self.numdigits():
- self.size = i
- if self.numdigits() == 1 and self._digits[0] == NULLDIGIT:
+ if self.numdigits() == 0:
self.sign = 0
self._digits = [NULLDIGIT]
-
- _normalize._always_inline_ = True
-
- @jit.elidable
+ return
+ i = self.numdigits()
+ while i > 1 and self.digit(i - 1) == 0:
+ i -= 1
+ assert i >= 1
+ if i != self.numdigits():
+ self._digits = self._digits[:i]
+ if self.numdigits() == 1 and self.digit(0) == 0:
+ self.sign = 0
+
def bit_length(self):
i = self.numdigits()
- if i == 1 and self._digits[0] == NULLDIGIT:
+ if i == 1 and self.digit(0) == 0:
return 0
msd = self.digit(i - 1)
msd_bits = 0
@@ -881,10 +664,6 @@
return "<rbigint digits=%s, sign=%s, %s>" % (self._digits,
self.sign, self.str())
-ONERBIGINT = rbigint([ONEDIGIT], 1, 1)
-ONENEGATIVERBIGINT = rbigint([ONEDIGIT], -1, 1)
-NULLRBIGINT = rbigint()
-
#_________________________________________________________________
# Helper Functions
@@ -899,14 +678,16 @@
# Perform a modular reduction, X = X % c, but leave X alone if c
# is NULL.
if c is not None:
- res = res.mod(c)
-
+ res, temp = res.divmod(c)
+ res = temp
return res
+
+
def digits_from_nonneg_long(l):
digits = []
while True:
- digits.append(_store_digit(_mask_digit(l & MASK)))
+ digits.append(_store_digit(intmask(l & MASK)))
l = l >> SHIFT
if not l:
return digits[:] # to make it non-resizable
@@ -966,9 +747,9 @@
if size_a < size_b:
a, b = b, a
size_a, size_b = size_b, size_a
- z = rbigint([NULLDIGIT] * (size_a + 1), 1)
- i = UDIGIT_TYPE(0)
- carry = UDIGIT_TYPE(0)
+ z = rbigint([NULLDIGIT] * (a.numdigits() + 1), 1)
+ i = 0
+ carry = r_uint(0)
while i < size_b:
carry += a.udigit(i) + b.udigit(i)
z.setdigit(i, carry)
@@ -985,11 +766,6 @@
def _x_sub(a, b):
""" Subtract the absolute values of two integers. """
-
- # Special casing.
- if a is b:
- return NULLRBIGINT
-
size_a = a.numdigits()
size_b = b.numdigits()
sign = 1
@@ -1005,15 +781,14 @@
while i >= 0 and a.digit(i) == b.digit(i):
i -= 1
if i < 0:
- return NULLRBIGINT
+ return rbigint()
if a.digit(i) < b.digit(i):
sign = -1
a, b = b, a
size_a = size_b = i+1
-
- z = rbigint([NULLDIGIT] * size_a, sign, size_a)
- borrow = UDIGIT_TYPE(0)
- i = _load_unsigned_digit(0)
+ z = rbigint([NULLDIGIT] * size_a, sign)
+ borrow = r_uint(0)
+ i = 0
while i < size_b:
# The following assumes unsigned arithmetic
# works modulo 2**N for some N>SHIFT.
@@ -1026,20 +801,14 @@
borrow = a.udigit(i) - borrow
z.setdigit(i, borrow)
borrow >>= SHIFT
- borrow &= 1
+ borrow &= 1 # Keep only one sign bit
i += 1
-
assert borrow == 0
z._normalize()
return z
-# A neat little table of power of twos.
-ptwotable = {}
-for x in range(SHIFT-1):
- ptwotable[r_longlong(2 << x)] = x+1
- ptwotable[r_longlong(-2 << x)] = x+1
-
-def _x_mul(a, b, digit=0):
+
+def _x_mul(a, b):
"""
Grade school multiplication, ignoring the signs.
Returns the absolute value of the product, or None if error.
@@ -1047,19 +816,19 @@
size_a = a.numdigits()
size_b = b.numdigits()
-
+ z = rbigint([NULLDIGIT] * (size_a + size_b), 1)
if a is b:
# Efficient squaring per HAC, Algorithm 14.16:
# http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
# Gives slightly less than a 2x speedup when a == b,
# via exploiting that each entry in the multiplication
# pyramid appears twice (except for the size_a squares).
- z = rbigint([NULLDIGIT] * (size_a + size_b), 1)
- i = UDIGIT_TYPE(0)
+ i = 0
while i < size_a:
f = a.widedigit(i)
pz = i << 1
pa = i + 1
+ paend = size_a
carry = z.widedigit(pz) + f * f
z.setdigit(pz, carry)
@@ -1070,12 +839,13 @@
# Now f is added in twice in each column of the
# pyramid it appears. Same as adding f<<1 once.
f <<= 1
- while pa < size_a:
+ while pa < paend:
carry += z.widedigit(pz) + a.widedigit(pa) * f
pa += 1
z.setdigit(pz, carry)
pz += 1
carry >>= SHIFT
+ assert carry <= (_widen_digit(MASK) << 1)
if carry:
carry += z.widedigit(pz)
z.setdigit(pz, carry)
@@ -1085,128 +855,30 @@
z.setdigit(pz, z.widedigit(pz) + carry)
assert (carry >> SHIFT) == 0
i += 1
- z._normalize()
- return z
-
- elif digit:
- if digit & (digit - 1) == 0:
- return b.lqshift(ptwotable[digit])
-
- # Even if it's not power of two it can still be useful.
- return _muladd1(b, digit)
-
- z = rbigint([NULLDIGIT] * (size_a + size_b), 1)
- # gradeschool long mult
- i = UDIGIT_TYPE(0)
- while i < size_a:
- carry = 0
- f = a.widedigit(i)
- pz = i
- pb = 0
- while pb < size_b:
- carry += z.widedigit(pz) + b.widedigit(pb) * f
- pb += 1
- z.setdigit(pz, carry)
- pz += 1
- carry >>= SHIFT
- assert carry <= MASK
- if carry:
- assert pz >= 0
- z.setdigit(pz, z.widedigit(pz) + carry)
- assert (carry >> SHIFT) == 0
- i += 1
+ else:
+ # a is not the same as b -- gradeschool long mult
+ i = 0
+ while i < size_a:
+ carry = 0
+ f = a.widedigit(i)
+ pz = i
+ pb = 0
+ pbend = size_b
+ while pb < pbend:
+ carry += z.widedigit(pz) + b.widedigit(pb) * f
+ pb += 1
+ z.setdigit(pz, carry)
+ pz += 1
+ carry >>= SHIFT
+ assert carry <= MASK
+ if carry:
+ z.setdigit(pz, z.widedigit(pz) + carry)
+ assert (carry >> SHIFT) == 0
+ i += 1
z._normalize()
return z
-def _tcmul_split(n):
- """
- A helper for Karatsuba multiplication (k_mul).
- Takes a bigint "n" and an integer "size" representing the place to
- split, and sets low and high such that abs(n) == (high << (size * 2) + (mid << size) + low,
- viewing the shift as being by digits. The sign bit is ignored, and
- the return values are >= 0.
- """
- size_n = n.numdigits() // 3
- lo = rbigint(n._digits[:size_n], 1)
- mid = rbigint(n._digits[size_n:size_n * 2], 1)
- hi = rbigint(n._digits[size_n *2:], 1)
- lo._normalize()
- mid._normalize()
- hi._normalize()
- return hi, mid, lo
-
-THREERBIGINT = rbigint.fromint(3)
-def _tc_mul(a, b):
- """
- Toom Cook
- """
- asize = a.numdigits()
- bsize = b.numdigits()
-
- # Split a & b into hi, mid and lo pieces.
- shift = bsize // 3
- ah, am, al = _tcmul_split(a)
- assert ah.sign == 1 # the split isn't degenerate
-
- if a is b:
- bh = ah
- bm = am
- bl = al
- else:
- bh, bm, bl = _tcmul_split(b)
-
- # 2. ahl, bhl
- ahl = al.add(ah)
- bhl = bl.add(bh)
-
- # Points
- v0 = al.mul(bl)
- v1 = ahl.add(bm).mul(bhl.add(bm))
-
- vn1 = ahl.sub(bm).mul(bhl.sub(bm))
- v2 = al.add(am.lqshift(1)).add(ah.lshift(2)).mul(bl.add(bm.lqshift(1)).add(bh.lqshift(2)))
-
- vinf = ah.mul(bh)
-
- # Construct
- t1 = v0.mul(THREERBIGINT).add(vn1.lqshift(1)).add(v2)
- _inplace_divrem1(t1, t1, 6)
- t1 = t1.sub(vinf.lqshift(1))
- t2 = v1
- _v_iadd(t2, 0, t2.numdigits(), vn1, vn1.numdigits())
- _v_rshift(t2, t2, t2.numdigits(), 1)
-
- r1 = v1.sub(t1)
- r2 = t2
- _v_isub(r2, 0, r2.numdigits(), v0, v0.numdigits())
- r2 = r2.sub(vinf)
- r3 = t1
- _v_isub(r3, 0, r3.numdigits(), t2, t2.numdigits())
-
- # Now we fit t+ t2 + t4 into the new string.
- # Now we got to add the r1 and r3 in the mid shift.
- # Allocate result space.
- ret = rbigint([NULLDIGIT] * (4 * shift + vinf.numdigits() + 1), 1) # This is because of the size of vinf
-
- ret._digits[:v0.numdigits()] = v0._digits
- assert t2.sign >= 0
- assert 2*shift + t2.numdigits() < ret.numdigits()
- ret._digits[shift * 2:shift * 2+r2.numdigits()] = r2._digits
- assert vinf.sign >= 0
- assert 4*shift + vinf.numdigits() <= ret.numdigits()
- ret._digits[shift*4:shift*4+vinf.numdigits()] = vinf._digits
-
-
- i = ret.numdigits() - shift
- _v_iadd(ret, shift * 3, i, r3, r3.numdigits())
- _v_iadd(ret, shift, i, r1, r1.numdigits())
-
-
- ret._normalize()
- return ret
-
-
def _kmul_split(n, size):
"""
A helper for Karatsuba multiplication (k_mul).
@@ -1232,7 +904,6 @@
"""
asize = a.numdigits()
bsize = b.numdigits()
-
# (ah*X+al)(bh*X+bl) = ah*bh*X*X + (ah*bl + al*bh)*X + al*bl
# Let k = (ah+al)*(bh+bl) = ah*bl + al*bh + ah*bh + al*bl
# Then the original product is
@@ -1240,6 +911,30 @@
# By picking X to be a power of 2, "*X" is just shifting, and it's
# been reduced to 3 multiplies on numbers half the size.
+ # We want to split based on the larger number; fiddle so that b
+ # is largest.
+ if asize > bsize:
+ a, b, asize, bsize = b, a, bsize, asize
+
+ # Use gradeschool math when either number is too small.
+ if a is b:
+ i = KARATSUBA_SQUARE_CUTOFF
+ else:
+ i = KARATSUBA_CUTOFF
+ if asize <= i:
+ if a.sign == 0:
+ return rbigint() # zero
+ else:
+ return _x_mul(a, b)
+
+ # If a is small compared to b, splitting on b gives a degenerate
+ # case with ah==0, and Karatsuba may be (even much) less efficient
+ # than "grade school" then. However, we can still win, by viewing
+ # b as a string of "big digits", each of width a->ob_size. That
+ # leads to a sequence of balanced calls to k_mul.
+ if 2 * asize <= bsize:
+ return _k_lopsided_mul(a, b)
+
# Split a & b into hi & lo pieces.
shift = bsize >> 1
ah, al = _kmul_split(a, shift)
@@ -1270,7 +965,7 @@
ret = rbigint([NULLDIGIT] * (asize + bsize), 1)
# 2. t1 <- ah*bh, and copy into high digits of result.
- t1 = ah.mul(bh)
+ t1 = _k_mul(ah, bh)
assert t1.sign >= 0
assert 2*shift + t1.numdigits() <= ret.numdigits()
ret._digits[2*shift : 2*shift + t1.numdigits()] = t1._digits
@@ -1283,7 +978,7 @@
## i * sizeof(digit));
# 3. t2 <- al*bl, and copy into the low digits.
- t2 = al.mul(bl)
+ t2 = _k_mul(al, bl)
assert t2.sign >= 0
assert t2.numdigits() <= 2*shift # no overlap with high digits
ret._digits[:t2.numdigits()] = t2._digits
@@ -1308,7 +1003,7 @@
else:
t2 = _x_add(bh, bl)
- t3 = t1.mul(t2)
+ t3 = _k_mul(t1, t2)
assert t3.sign >=0
# Add t3. It's not obvious why we can't run out of room here.
@@ -1386,9 +1081,8 @@
# Successive slices of b are copied into bslice.
#bslice = rbigint([0] * asize, 1)
# XXX we cannot pre-allocate, see comments below!
- # XXX prevent one list from being created.
- bslice = rbigint(sign = 1)
-
+ bslice = rbigint([NULLDIGIT], 1)
+
nbdone = 0;
while bsize > 0:
nbtouse = min(bsize, asize)
@@ -1400,12 +1094,11 @@
# way to store the size, instead of resizing the list!
# XXX change the implementation, encoding length via the sign.
bslice._digits = b._digits[nbdone : nbdone + nbtouse]
- bslice.size = nbtouse
product = _k_mul(a, bslice)
# Add into result.
_v_iadd(ret, nbdone, ret.numdigits() - nbdone,
- product, product.numdigits())
+ product, product.numdigits())
bsize -= nbtouse
nbdone += nbtouse
@@ -1413,6 +1106,7 @@
ret._normalize()
return ret
+
def _inplace_divrem1(pout, pin, n, size=0):
"""
Divide bigint pin by non-zero digit n, storing quotient
@@ -1423,14 +1117,13 @@
if not size:
size = pin.numdigits()
size -= 1
-
while size >= 0:
rem = (rem << SHIFT) + pin.widedigit(size)
hi = rem // n
pout.setdigit(size, hi)
rem -= hi * n
size -= 1
- return rem & MASK
+ return _mask_digit(rem)
def _divrem1(a, n):
"""
@@ -1439,9 +1132,8 @@
The sign of a is ignored; n should not be zero.
"""
assert n > 0 and n <= MASK
-
size = a.numdigits()
- z = rbigint([NULLDIGIT] * size, 1, size)
+ z = rbigint([NULLDIGIT] * size, 1)
rem = _inplace_divrem1(z, a, n)
z._normalize()
return z, rem
@@ -1456,18 +1148,20 @@
carry = r_uint(0)
assert m >= n
- i = _load_unsigned_digit(xofs)
+ i = xofs
iend = xofs + n
while i < iend:
carry += x.udigit(i) + y.udigit(i-xofs)
x.setdigit(i, carry)
carry >>= SHIFT
+ assert (carry & 1) == carry
i += 1
iend = xofs + m
while carry and i < iend:
carry += x.udigit(i)
x.setdigit(i, carry)
carry >>= SHIFT
+ assert (carry & 1) == carry
i += 1
return carry
@@ -1481,7 +1175,7 @@
borrow = r_uint(0)
assert m >= n
- i = _load_unsigned_digit(xofs)
+ i = xofs
iend = xofs + n
while i < iend:
borrow = x.udigit(i) - y.udigit(i-xofs) - borrow
@@ -1498,10 +1192,10 @@
i += 1
return borrow
+
def _muladd1(a, n, extra=0):
"""Multiply by a single digit and add a single digit, ignoring the sign.
"""
-
size_a = a.numdigits()
z = rbigint([NULLDIGIT] * (size_a+1), 1)
assert extra & MASK == extra
@@ -1515,94 +1209,45 @@
z.setdigit(i, carry)
z._normalize()
return z
-_muladd1._annspecialcase_ = "specialize:argtype(2)"
-def _v_lshift(z, a, m, d):
- """ Shift digit vector a[0:m] d bits left, with 0 <= d < SHIFT. Put
- * result in z[0:m], and return the d bits shifted out of the top.
- """
-
- carry = 0
- assert 0 <= d and d < SHIFT
- for i in range(m):
- acc = a.widedigit(i) << d | carry
- z.setdigit(i, acc)
- carry = acc >> SHIFT
-
- return carry
-def _v_rshift(z, a, m, d):
- """ Shift digit vector a[0:m] d bits right, with 0 <= d < PyLong_SHIFT. Put
- * result in z[0:m], and return the d bits shifted out of the bottom.
- """
-
- carry = 0
- acc = _widen_digit(0)
- mask = (1 << d) - 1
-
- assert 0 <= d and d < SHIFT
- for i in range(m-1, 0, -1):
- acc = carry << SHIFT | a.digit(i)
- carry = acc & mask
- z.setdigit(i, acc >> d)
-
- return carry
def _x_divrem(v1, w1):
""" Unsigned bigint division with remainder -- the algorithm """
-
size_w = w1.numdigits()
- d = (UDIGIT_TYPE(MASK)+1) // (w1.udigit(abs(size_w-1)) + 1)
+ d = (r_uint(MASK)+1) // (w1.udigit(size_w-1) + 1)
assert d <= MASK # because the first digit of w1 is not zero
- d = UDIGIT_MASK(d)
+ d = intmask(d)
v = _muladd1(v1, d)
w = _muladd1(w1, d)
size_v = v.numdigits()
size_w = w.numdigits()
- assert size_w > 1 # (Assert checks by div()
+ assert size_v >= size_w and size_w > 1 # Assert checks by div()
- """v = rbigint([NULLDIGIT] * (size_v + 1))
- w = rbigint([NULLDIGIT] * (size_w))
-
- d = SHIFT - bits_in_digit(w1.digit(size_w-1))
- carry = _v_lshift(w, w1, size_w, d)
- assert carry == 0
- carrt = _v_lshift(v, v1, size_v, d)
- if carry != 0 or v.digit(size_v - 1) >= w.digit(size_w-1):
- v.setdigit(size_v, carry)
- size_v += 1"""
-
size_a = size_v - size_w + 1
- assert size_a >= 0
- a = rbigint([NULLDIGIT] * size_a, 1, size_a)
+ a = rbigint([NULLDIGIT] * size_a, 1)
- wm1 = w.widedigit(abs(size_w-1))
- wm2 = w.widedigit(abs(size_w-2))
j = size_v
k = size_a - 1
while k >= 0:
- assert j >= 2
if j >= size_v:
vj = 0
else:
vj = v.widedigit(j)
-
carry = 0
- vj1 = v.widedigit(abs(j-1))
-
- if vj == wm1:
+
+ if vj == w.widedigit(size_w-1):
q = MASK
- r = 0
else:
- vv = ((vj << SHIFT) | vj1)
- q = vv // wm1
- r = _widen_digit(vv) - wm1 * q
-
- vj2 = v.widedigit(abs(j-2))
- while wm2 * q > ((r << SHIFT) | vj2):
+ q = ((vj << SHIFT) + v.widedigit(j-1)) // w.widedigit(size_w-1)
+
+ while (w.widedigit(size_w-2) * q >
+ ((
+ (vj << SHIFT)
+ + v.widedigit(j-1)
+ - q * w.widedigit(size_w-1)
+ ) << SHIFT)
+ + v.widedigit(j-2)):
q -= 1
- r += wm1
- if r > MASK:
- break
i = 0
while i < size_w and i+k < size_v:
z = w.widedigit(i) * q
@@ -1637,99 +1282,10 @@
k -= 1
a._normalize()
- _inplace_divrem1(v, v, d, size_v)
- v._normalize()
- return a, v
+ rem, _ = _divrem1(v, d)
+ return a, rem
- """
- Didn't work as expected. Someone want to look over this?
- size_v = v1.numdigits()
- size_w = w1.numdigits()
-
- assert size_v >= size_w and size_w >= 2
-
- v = rbigint([NULLDIGIT] * (size_v + 1))
- w = rbigint([NULLDIGIT] * size_w)
-
- # Normalization
- d = SHIFT - bits_in_digit(w1.digit(size_w-1))
- carry = _v_lshift(w, w1, size_w, d)
- assert carry == 0
- carry = _v_lshift(v, v1, size_v, d)
- if carry != 0 or v.digit(size_v-1) >= w.digit(size_w-1):
- v.setdigit(size_v, carry)
- size_v += 1
-
- # 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
- assert k >= 0
-
- a = rbigint([NULLDIGIT] * k)
-
- k -= 1
- wm1 = w.digit(size_w-1)
- wm2 = w.digit(size_w-2)
-
- j = size_v
-
- while k >= 0:
- # inner loop: divide vk[0:size_w+1] by w[0:size_w], giving
- # single-digit quotient q, remainder in vk[0:size_w].
-
- vtop = v.widedigit(size_w)
- assert vtop <= wm1
-
- vv = vtop << SHIFT | v.digit(size_w-1)
-
- q = vv / wm1
- r = vv - _widen_digit(wm1) * q
-
- # estimate quotient digit q; may overestimate by 1 (rare)
- while wm2 * q > ((r << SHIFT) | v.digit(size_w-2)):
- q -= 1
-
- r+= wm1
- if r >= SHIFT:
- break
-
- assert q <= BASE
-
- # subtract q*w0[0:size_w] from vk[0:size_w+1]
- zhi = 0
- for i in range(size_w):
- #invariants: -BASE <= -q <= zhi <= 0;
- # -BASE * q <= z < ASE
- z = v.widedigit(i+k) + zhi - (q * w.widedigit(i))
- v.setdigit(i+k, z)
- zhi = z >> SHIFT
-
- # add w back if q was too large (this branch taken rarely)
- assert vtop + zhi == -1 or vtop + zhi == 0
- if vtop + zhi < 0:
- carry = 0
- for i in range(size_w):
- carry += v.digit(i+k) + w.digit(i)
- v.setdigit(i+k, carry)
- carry >>= SHIFT
-
- q -= 1
-
- assert q < BASE
-
- a.setdigit(k, q)
- j -= 1
- k -= 1
-
- carry = _v_rshift(w, v, size_w, d)
- assert carry == 0
-
- a._normalize()
- w._normalize()
- return a, w"""
-
def _divrem(a, b):
""" Long division with remainder, top-level routine """
size_a = a.numdigits()
@@ -1740,12 +1296,14 @@
if (size_a < size_b or
(size_a == size_b and
- a.digit(abs(size_a-1)) < b.digit(abs(size_b-1)))):
+ a.digit(size_a-1) < b.digit(size_b-1))):
# |a| < |b|
- return NULLRBIGINT, a# result is 0
+ z = rbigint() # result is 0
+ rem = a
+ return z, rem
if size_b == 1:
z, urem = _divrem1(a, b.digit(0))
- rem = rbigint([_store_digit(urem)], int(urem != 0), 1)
+ rem = rbigint([_store_digit(urem)], int(urem != 0))
else:
z, rem = _x_divrem(a, b)
# Set the signs.
@@ -2103,14 +1661,14 @@
power += 1
# Get a scratch area for repeated division.
- scratch = rbigint([NULLDIGIT] * size, 1, size)
+ scratch = rbigint([NULLDIGIT] * size, 1)
# Repeatedly divide by powbase.
while 1:
ntostore = power
rem = _inplace_divrem1(scratch, pin, powbase, size)
pin = scratch # no need to use a again
- if pin._digits[size - 1] == NULLDIGIT:
+ if pin.digit(size - 1) == 0:
size -= 1
# Break rem into digits.
@@ -2200,7 +1758,7 @@
else:
size_z = max(size_a, size_b)
- z = rbigint([NULLDIGIT] * size_z, 1, size_z)
+ z = rbigint([NULLDIGIT] * size_z, 1)
for i in range(size_z):
if i < size_a:
@@ -2211,7 +1769,6 @@
digb = b.digit(i) ^ maskb
else:
digb = maskb
-
if op == '&':
z.setdigit(i, diga & digb)
elif op == '|':
@@ -2222,8 +1779,7 @@
z._normalize()
if negz == 0:
return z
-
- return z.inplace_invert()
+ return z.invert()
_bitwise._annspecialcase_ = "specialize:arg(1)"
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
@@ -1,9 +1,9 @@
from __future__ import division
import py
-import operator, sys, array
+import operator, sys
from random import random, randint, sample
from pypy.rlib.rbigint import rbigint, SHIFT, MASK, KARATSUBA_CUTOFF
-from pypy.rlib.rbigint import _store_digit, _mask_digit, _tc_mul
+from pypy.rlib.rbigint import _store_digit
from pypy.rlib import rbigint as lobj
from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask
from pypy.rpython.test.test_llinterp import interpret
@@ -17,7 +17,6 @@
for op in "add sub mul".split():
r1 = getattr(rl_op1, op)(rl_op2)
r2 = getattr(operator, op)(op1, op2)
- print op, op1, op2
assert r1.tolong() == r2
def test_frombool(self):
@@ -94,7 +93,6 @@
rl_op2 = rbigint.fromint(op2)
r1 = rl_op1.mod(rl_op2)
r2 = op1 % op2
- print op1, op2
assert r1.tolong() == r2
def test_pow(self):
@@ -122,7 +120,7 @@
def bigint(lst, sign):
for digit in lst:
assert digit & MASK == digit # wrongly written test!
- return rbigint(map(_store_digit, map(_mask_digit, lst)), sign)
+ return rbigint(map(_store_digit, lst), sign)
class Test_rbigint(object):
@@ -142,20 +140,19 @@
# rbigint.digits_for_most_neg_long(-sys.maxint-1), -1)
def test_args_from_int(self):
- BASE = 1 << 31 # Can't can't shift here. Shift might be from longlonglong
+ BASE = 1 << SHIFT
MAX = int(BASE-1)
assert rbigint.fromrarith_int(0).eq(bigint([0], 0))
assert rbigint.fromrarith_int(17).eq(bigint([17], 1))
assert rbigint.fromrarith_int(MAX).eq(bigint([MAX], 1))
- # No longer true.
- """assert rbigint.fromrarith_int(r_longlong(BASE)).eq(bigint([0, 1], 1))
+ assert rbigint.fromrarith_int(r_longlong(BASE)).eq(bigint([0, 1], 1))
assert rbigint.fromrarith_int(r_longlong(BASE**2)).eq(
- bigint([0, 0, 1], 1))"""
+ bigint([0, 0, 1], 1))
assert rbigint.fromrarith_int(-17).eq(bigint([17], -1))
assert rbigint.fromrarith_int(-MAX).eq(bigint([MAX], -1))
- """assert rbigint.fromrarith_int(-MAX-1).eq(bigint([0, 1], -1))
+ assert rbigint.fromrarith_int(-MAX-1).eq(bigint([0, 1], -1))
assert rbigint.fromrarith_int(r_longlong(-(BASE**2))).eq(
- bigint([0, 0, 1], -1))"""
+ bigint([0, 0, 1], -1))
# assert rbigint.fromrarith_int(-sys.maxint-1).eq((
# rbigint.digits_for_most_neg_long(-sys.maxint-1), -1)
@@ -343,7 +340,6 @@
def test_pow_lll(self):
- return
x = 10L
y = 2L
z = 13L
@@ -363,7 +359,7 @@
for i in (10L, 5L, 0L)]
py.test.raises(ValueError, f1.pow, f2, f3)
#
- MAX = 1E20
+ MAX = 1E40
x = long(random() * MAX) + 1
y = long(random() * MAX) + 1
z = long(random() * MAX) + 1
@@ -407,7 +403,7 @@
def test_normalize(self):
f1 = bigint([1, 0], 1)
f1._normalize()
- assert f1.size == 1
+ assert len(f1._digits) == 1
f0 = bigint([0], 0)
assert f1.sub(f1).eq(f0)
@@ -431,7 +427,7 @@
res2 = f1.rshift(int(y)).tolong()
assert res1 == x << y
assert res2 == x >> y
-
+
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]):
@@ -457,12 +453,6 @@
'-!....!!..!!..!.!!.!......!...!...!!!........!')
assert x.format('abcdefghijkl', '<<', '>>') == '-<<cakdkgdijffjf>>'
- def test_tc_mul(self):
- a = rbigint.fromlong(1<<200)
- b = rbigint.fromlong(1<<300)
- print _tc_mul(a, b)
- assert _tc_mul(a, b).tolong() == ((1<<300)*(1<<200))
-
def test_overzelous_assertion(self):
a = rbigint.fromlong(-1<<10000)
b = rbigint.fromlong(-1<<3000)
@@ -530,31 +520,27 @@
def test__x_divrem(self):
x = 12345678901234567890L
for i in range(100):
- y = long(randint(0, 1 << 60))
- y <<= 60
- y += randint(0, 1 << 60)
+ y = long(randint(0, 1 << 30))
+ y <<= 30
+ y += randint(0, 1 << 30)
f1 = rbigint.fromlong(x)
f2 = rbigint.fromlong(y)
div, rem = lobj._x_divrem(f1, f2)
- _div, _rem = divmod(x, y)
- print div.tolong() == _div
- print rem.tolong() == _rem
+ assert div.tolong(), rem.tolong() == divmod(x, y)
def test__divrem(self):
x = 12345678901234567890L
for i in range(100):
- y = long(randint(0, 1 << 60))
- y <<= 60
- y += randint(0, 1 << 60)
+ y = long(randint(0, 1 << 30))
+ y <<= 30
+ y += randint(0, 1 << 30)
for sx, sy in (1, 1), (1, -1), (-1, -1), (-1, 1):
sx *= x
sy *= y
f1 = rbigint.fromlong(sx)
f2 = rbigint.fromlong(sy)
div, rem = lobj._x_divrem(f1, f2)
- _div, _rem = divmod(sx, sy)
- print div.tolong() == _div
- print rem.tolong() == _rem
+ assert div.tolong(), rem.tolong() == divmod(sx, sy)
# testing Karatsuba stuff
def test__v_iadd(self):
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -138,9 +138,6 @@
llmemory.GCREF: ctypes.c_void_p,
llmemory.WeakRef: ctypes.c_void_p, # XXX
})
-
- if '__int128' in rffi.TYPES:
- _ctypes_cache[rffi.__INT128] = ctypes.c_longlong # XXX: Not right at all. But for some reason, It started by while doing JIT compile after a merge with default. Can't extend ctypes, because thats a python standard, right?
# for unicode strings, do not use ctypes.c_wchar because ctypes
# automatically converts arrays into unicode strings.
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -329,30 +329,6 @@
'ullong_rshift': LLOp(canfold=True), # args (r_ulonglong, int)
'ullong_xor': LLOp(canfold=True),
- 'lllong_is_true': LLOp(canfold=True),
- 'lllong_neg': LLOp(canfold=True),
- 'lllong_abs': LLOp(canfold=True),
- 'lllong_invert': LLOp(canfold=True),
-
- 'lllong_add': LLOp(canfold=True),
- 'lllong_sub': LLOp(canfold=True),
- 'lllong_mul': LLOp(canfold=True),
- 'lllong_floordiv': LLOp(canfold=True),
- 'lllong_floordiv_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'lllong_mod': LLOp(canfold=True),
- 'lllong_mod_zer': LLOp(canraise=(ZeroDivisionError,), tryfold=True),
- 'lllong_lt': LLOp(canfold=True),
- 'lllong_le': LLOp(canfold=True),
- 'lllong_eq': LLOp(canfold=True),
- 'lllong_ne': LLOp(canfold=True),
- 'lllong_gt': LLOp(canfold=True),
- 'lllong_ge': LLOp(canfold=True),
- 'lllong_and': LLOp(canfold=True),
- 'lllong_or': LLOp(canfold=True),
- 'lllong_lshift': LLOp(canfold=True), # args (r_longlonglong, int)
- 'lllong_rshift': LLOp(canfold=True), # args (r_longlonglong, int)
- 'lllong_xor': LLOp(canfold=True),
-
'cast_primitive': LLOp(canfold=True),
'cast_bool_to_int': LLOp(canfold=True),
'cast_bool_to_uint': LLOp(canfold=True),
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -1,7 +1,7 @@
import py
from pypy.rlib.rarithmetic import (r_int, r_uint, intmask, r_singlefloat,
- r_ulonglong, r_longlong, r_longfloat, r_longlonglong,
- base_int, normalizedinttype, longlongmask, longlonglongmask)
+ r_ulonglong, r_longlong, r_longfloat,
+ base_int, normalizedinttype, longlongmask)
from pypy.rlib.objectmodel import Symbolic
from pypy.tool.uid import Hashable
from pypy.tool.identity_dict import identity_dict
@@ -667,7 +667,6 @@
_numbertypes = {int: Number("Signed", int, intmask)}
_numbertypes[r_int] = _numbertypes[int]
-_numbertypes[r_longlonglong] = Number("SignedLongLongLong", r_longlonglong, longlonglongmask)
if r_longlong is not r_int:
_numbertypes[r_longlong] = Number("SignedLongLong", r_longlong,
longlongmask)
@@ -690,7 +689,6 @@
Signed = build_number("Signed", int)
Unsigned = build_number("Unsigned", r_uint)
SignedLongLong = build_number("SignedLongLong", r_longlong)
-SignedLongLongLong = build_number("SignedLongLongLong", r_longlonglong)
UnsignedLongLong = build_number("UnsignedLongLong", r_ulonglong)
Float = Primitive("Float", 0.0) # C type 'double'
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -20,7 +20,7 @@
# global synonyms for some types
from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong, r_longlonglong
+from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong
from pypy.rpython.lltypesystem.llmemory import AddressAsInt
if r_longlong is r_int:
@@ -29,10 +29,6 @@
else:
r_longlong_arg = r_longlong
r_longlong_result = r_longlong
-
-
-r_longlonglong_arg = r_longlonglong
-r_longlonglong_result = r_longlonglong
argtype_by_name = {
'int': (int, long),
@@ -40,7 +36,6 @@
'uint': r_uint,
'llong': r_longlong_arg,
'ullong': r_ulonglong,
- 'lllong': r_longlonglong,
}
def no_op(x):
@@ -288,22 +283,6 @@
r -= y
return r
-def op_lllong_floordiv(x, y):
- assert isinstance(x, r_longlonglong_arg)
- assert isinstance(y, r_longlonglong_arg)
- r = x//y
- if x^y < 0 and x%y != 0:
- r += 1
- return r
-
-def op_lllong_mod(x, y):
- assert isinstance(x, r_longlonglong_arg)
- assert isinstance(y, r_longlonglong_arg)
- r = x%y
- if x^y < 0 and x%y != 0:
- r -= y
- return r
-
def op_uint_lshift(x, y):
assert isinstance(x, r_uint)
assert is_valid_int(y)
@@ -324,16 +303,6 @@
assert is_valid_int(y)
return r_longlong_result(x >> y)
-def op_lllong_lshift(x, y):
- assert isinstance(x, r_longlonglong_arg)
- assert is_valid_int(y)
- return r_longlonglong_result(x << y)
-
-def op_lllong_rshift(x, y):
- assert isinstance(x, r_longlonglong_arg)
- assert is_valid_int(y)
- return r_longlonglong_result(x >> y)
-
def op_ullong_lshift(x, y):
assert isinstance(x, r_ulonglong)
assert isinstance(y, int)
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -11,7 +11,7 @@
from pypy.rlib import rarithmetic, rgc
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rlib.unroll import unrolling_iterable
-from pypy.rpython.tool.rfficache import platform, sizeof_c_type
+from pypy.rpython.tool.rfficache import platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.annlowlevel import llhelper
from pypy.rlib.objectmodel import we_are_translated
@@ -19,7 +19,6 @@
from pypy.rlib import jit
from pypy.rpython.lltypesystem import llmemory
from pypy.rlib.rarithmetic import maxint, LONG_BIT
-from pypy.translator.platform import CompilationError
import os, sys
class CConstant(Symbolic):
@@ -438,14 +437,6 @@
'size_t', 'time_t', 'wchar_t',
'uintptr_t', 'intptr_t',
'void*'] # generic pointer type
-
-# This is a bit of a hack since we can't use rffi_platform here.
-try:
- sizeof_c_type('__int128')
- TYPES += ['__int128']
-except CompilationError:
- pass
-
_TYPES_ARE_UNSIGNED = set(['size_t', 'uintptr_t']) # plus "unsigned *"
if os.name != 'nt':
TYPES.append('mode_t')
diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -4,8 +4,7 @@
from pypy.objspace.flow.operation import op_appendices
from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \
Void, Char, UniChar, malloc, pyobjectptr, UnsignedLongLong, \
- SignedLongLong, build_number, Number, cast_primitive, typeOf, \
- SignedLongLongLong
+ SignedLongLong, build_number, Number, cast_primitive, typeOf
from pypy.rpython.rmodel import IntegerRepr, inputconst
from pypy.rpython.robject import PyObjRepr, pyobj_repr
from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \
@@ -33,10 +32,10 @@
signed_repr = getintegerrepr(Signed, 'int_')
signedlonglong_repr = getintegerrepr(SignedLongLong, 'llong_')
-signedlonglonglong_repr = getintegerrepr(SignedLongLongLong, 'lllong_')
unsigned_repr = getintegerrepr(Unsigned, 'uint_')
unsignedlonglong_repr = getintegerrepr(UnsignedLongLong, 'ullong_')
+
class __extend__(pairtype(IntegerRepr, IntegerRepr)):
def convert_from_to((r_from, r_to), v, llops):
diff --git a/pypy/translator/c/primitive.py b/pypy/translator/c/primitive.py
--- a/pypy/translator/c/primitive.py
+++ b/pypy/translator/c/primitive.py
@@ -12,9 +12,6 @@
from pypy.rpython.lltypesystem.llarena import RoundedUpForAllocation
from pypy.translator.c.support import cdecl, barebonearray
-from pypy.rpython.tool import rffi_platform
-SUPPORT_INT128 = rffi_platform.has('__int128', '')
-
# ____________________________________________________________
#
# Primitives
@@ -250,5 +247,3 @@
define_c_primitive(rffi.ULONG, 'unsigned long', 'UL')
define_c_primitive(rffi.LONGLONG, 'long long', 'LL')
define_c_primitive(rffi.ULONGLONG, 'unsigned long long', 'ULL')
-if SUPPORT_INT128:
- define_c_primitive(rffi.__INT128, '__int128', 'LL') # Unless it's a 128bit platform, LL is the biggest
\ No newline at end of file
diff --git a/pypy/translator/c/src/int.h b/pypy/translator/c/src/int.h
--- a/pypy/translator/c/src/int.h
+++ b/pypy/translator/c/src/int.h
@@ -98,7 +98,7 @@
r = Py_ARITHMETIC_RIGHT_SHIFT(PY_LONG_LONG,x, (y))
#define OP_ULLONG_RSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
r = (x) >> (y)
-#define OP_LLLONG_RSHIFT(x,y,r) r = x >> y
+
#define OP_INT_LSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONG_BIT); \
r = (x) << (y)
@@ -106,7 +106,6 @@
r = (x) << (y)
#define OP_LLONG_LSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
r = (x) << (y)
-#define OP_LLLONG_LSHIFT(x,y,r) r = x << y
#define OP_ULLONG_LSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
r = (x) << (y)
@@ -121,7 +120,6 @@
#define OP_UINT_FLOORDIV(x,y,r) r = (x) / (y)
#define OP_LLONG_FLOORDIV(x,y,r) r = (x) / (y)
#define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
-#define OP_LLLONG_FLOORDIV(x,y,r) r = (x) / (y)
#define OP_INT_FLOORDIV_OVF(x,y,r) \
if ((y) == -1 && (x) == SIGNED_MIN) \
@@ -144,19 +142,12 @@
{ FAIL_ZER("integer division"); r=0; } \
else \
r = (x) / (y)
-
#define OP_ULLONG_FLOORDIV_ZER(x,y,r) \
if ((y) == 0) \
{ FAIL_ZER("unsigned integer division"); r=0; } \
else \
r = (x) / (y)
-
-#define OP_LLLONG_FLOORDIV_ZER(x,y,r) \
- if ((y) == 0) \
- { FAIL_ZER("integer division"); r=0; } \
- else \
- r = (x) / (y)
-
+
#define OP_INT_FLOORDIV_OVF_ZER(x,y,r) \
if ((y) == 0) \
{ FAIL_ZER("integer division"); r=0; } \
@@ -169,7 +160,6 @@
#define OP_UINT_MOD(x,y,r) r = (x) % (y)
#define OP_LLONG_MOD(x,y,r) r = (x) % (y)
#define OP_ULLONG_MOD(x,y,r) r = (x) % (y)
-#define OP_LLLONG_MOD(x,y,r) r = (x) % (y)
#define OP_INT_MOD_OVF(x,y,r) \
if ((y) == -1 && (x) == SIGNED_MIN) \
@@ -197,12 +187,6 @@
else \
r = (x) % (y)
-#define OP_LLLONG_MOD_ZER(x,y,r) \
- if ((y) == 0) \
- { FAIL_ZER("integer modulo"); r=0; } \
- else \
- r = (x) % (y)
-
#define OP_INT_MOD_OVF_ZER(x,y,r) \
if ((y) == 0) \
{ FAIL_ZER("integer modulo"); r=0; } \
@@ -222,13 +206,11 @@
#define OP_CAST_UINT_TO_INT(x,r) r = (Signed)(x)
#define OP_CAST_INT_TO_UINT(x,r) r = (Unsigned)(x)
#define OP_CAST_INT_TO_LONGLONG(x,r) r = (long long)(x)
-#define OP_CAST_INT_TO_LONGLONGLONG(x,r) r = (__int128)(x)
#define OP_CAST_CHAR_TO_INT(x,r) r = (Signed)((unsigned char)(x))
#define OP_CAST_INT_TO_CHAR(x,r) r = (char)(x)
#define OP_CAST_PTR_TO_INT(x,r) r = (Signed)(x) /* XXX */
#define OP_TRUNCATE_LONGLONG_TO_INT(x,r) r = (Signed)(x)
-#define OP_TRUNCATE_LONGLONGLONG_TO_INT(x,r) r = (Signed)(x)
#define OP_CAST_UNICHAR_TO_INT(x,r) r = (Signed)((Unsigned)(x)) /*?*/
#define OP_CAST_INT_TO_UNICHAR(x,r) r = (unsigned int)(x)
@@ -308,11 +290,6 @@
#define OP_LLONG_ABS OP_INT_ABS
#define OP_LLONG_INVERT OP_INT_INVERT
-#define OP_LLLONG_IS_TRUE OP_INT_IS_TRUE
-#define OP_LLLONG_NEG OP_INT_NEG
-#define OP_LLLONG_ABS OP_INT_ABS
-#define OP_LLLONG_INVERT OP_INT_INVERT
-
#define OP_LLONG_ADD OP_INT_ADD
#define OP_LLONG_SUB OP_INT_SUB
#define OP_LLONG_MUL OP_INT_MUL
@@ -326,19 +303,6 @@
#define OP_LLONG_OR OP_INT_OR
#define OP_LLONG_XOR OP_INT_XOR
-#define OP_LLLONG_ADD OP_INT_ADD
-#define OP_LLLONG_SUB OP_INT_SUB
-#define OP_LLLONG_MUL OP_INT_MUL
-#define OP_LLLONG_LT OP_INT_LT
-#define OP_LLLONG_LE OP_INT_LE
-#define OP_LLLONG_EQ OP_INT_EQ
-#define OP_LLLONG_NE OP_INT_NE
-#define OP_LLLONG_GT OP_INT_GT
-#define OP_LLLONG_GE OP_INT_GE
-#define OP_LLLONG_AND OP_INT_AND
-#define OP_LLLONG_OR OP_INT_OR
-#define OP_LLLONG_XOR OP_INT_XOR
-
#define OP_ULLONG_IS_TRUE OP_LLONG_IS_TRUE
#define OP_ULLONG_INVERT OP_LLONG_INVERT
#define OP_ULLONG_ADD OP_LLONG_ADD
diff --git a/pypy/translator/goal/targetbigintbenchmark.py b/pypy/translator/goal/targetbigintbenchmark.py
deleted file mode 100644
--- a/pypy/translator/goal/targetbigintbenchmark.py
+++ /dev/null
@@ -1,291 +0,0 @@
-#! /usr/bin/env python
-
-import os, sys
-from time import time
-from pypy.rlib.rbigint import rbigint, _k_mul, _tc_mul
-
-# __________ Entry point __________
-
-def entry_point(argv):
- """
- All benchmarks are run using --opt=2 and minimark gc (default).
-
- Benchmark changes:
- 2**N is a VERY heavy operation in default pypy, default to 10 million instead of 500,000 used like an hour to finish.
-
- A cutout with some benchmarks.
- Pypy default:
- mod by 2: 7.978181
- mod by 10000: 4.016121
- mod by 1024 (power of two): 3.966439
- Div huge number by 2**128: 2.906821
- rshift: 2.444589
- lshift: 2.500746
- Floordiv by 2: 4.431134
- Floordiv by 3 (not power of two): 4.404396
- 2**500000: 23.206724
- (2**N)**5000000 (power of two): 13.886118
- 10000 ** BIGNUM % 100 8.464378
- i = i * i: 10.121505
- n**10000 (not power of two): 16.296989
- Power of two ** power of two: 2.224125
- v = v * power of two 12.228391
- v = v * v 17.119933
- v = v + v 6.489957
- Sum: 142.686547
-
- Pypy with improvements:
- mod by 2: 0.003079
- mod by 10000: 3.148599
- mod by 1024 (power of two): 0.009572
- Div huge number by 2**128: 2.202237
- rshift: 2.240624
- lshift: 1.405393
- Floordiv by 2: 1.562338
- Floordiv by 3 (not power of two): 4.197440
- 2**500000: 0.033737
- (2**N)**5000000 (power of two): 0.046997
- 10000 ** BIGNUM % 100 1.321710
- i = i * i: 3.929341
- n**10000 (not power of two): 6.215907
- Power of two ** power of two: 0.014209
- v = v * power of two 3.506702
- v = v * v 6.253210
- v = v + v 2.772122
- Sum: 38.863216
-
- With SUPPORT_INT128 set to False
- mod by 2: 0.004103
- mod by 10000: 3.237434
- mod by 1024 (power of two): 0.016363
- Div huge number by 2**128: 2.836237
- rshift: 2.343860
- lshift: 1.172665
- Floordiv by 2: 1.537474
- Floordiv by 3 (not power of two): 3.796015
- 2**500000: 0.327269
- (2**N)**5000000 (power of two): 0.084709
- 10000 ** BIGNUM % 100 2.063215
- i = i * i: 8.109634
- n**10000 (not power of two): 11.243292
- Power of two ** power of two: 0.072559
- v = v * power of two 9.753532
- v = v * v 13.569841
- v = v + v 5.760466
- Sum: 65.928667
-
- """
- sumTime = 0.0
-
-
- """t = time()
- by = rbigint.fromint(2**62).lshift(1030000)
- for n in xrange(5000):
- by2 = by.lshift(63)
- _tc_mul(by, by2)
- by = by2
-
-
- _time = time() - t
- sumTime += _time
- print "Toom-cook effectivity _Tcmul 1030000-1035000 digits:", _time
-
- t = time()
- by = rbigint.fromint(2**62).lshift(1030000)
- for n in xrange(5000):
- by2 = by.lshift(63)
- _k_mul(by, by2)
- by = by2
-
-
- _time = time() - t
- sumTime += _time
- print "Toom-cook effectivity _kMul 1030000-1035000 digits:", _time"""
-
-
- V2 = rbigint.fromint(2)
- num = rbigint.pow(rbigint.fromint(100000000), rbigint.fromint(1024))
- t = time()
- for n in xrange(600000):
- rbigint.mod(num, V2)
-
- _time = time() - t
- sumTime += _time
- print "mod by 2: ", _time
-
- by = rbigint.fromint(10000)
- t = time()
- for n in xrange(300000):
- rbigint.mod(num, by)
-
- _time = time() - t
- sumTime += _time
- print "mod by 10000: ", _time
-
- V1024 = rbigint.fromint(1024)
- t = time()
- for n in xrange(300000):
- rbigint.mod(num, V1024)
-
- _time = time() - t
- sumTime += _time
- print "mod by 1024 (power of two): ", _time
-
- t = time()
- num = rbigint.pow(rbigint.fromint(100000000), rbigint.fromint(1024))
- by = rbigint.pow(rbigint.fromint(2), rbigint.fromint(128))
- for n in xrange(80000):
- rbigint.divmod(num, by)
-
-
- _time = time() - t
- sumTime += _time
- print "Div huge number by 2**128:", _time
-
- t = time()
- num = rbigint.fromint(1000000000)
- for n in xrange(160000000):
- rbigint.rshift(num, 16)
-
-
- _time = time() - t
- sumTime += _time
- print "rshift:", _time
-
- t = time()
- num = rbigint.fromint(1000000000)
- for n in xrange(160000000):
- rbigint.lshift(num, 4)
-
-
- _time = time() - t
- sumTime += _time
- print "lshift:", _time
-
- t = time()
- num = rbigint.fromint(100000000)
- for n in xrange(80000000):
- rbigint.floordiv(num, V2)
-
-
- _time = time() - t
- sumTime += _time
- print "Floordiv by 2:", _time
-
- t = time()
- num = rbigint.fromint(100000000)
- V3 = rbigint.fromint(3)
- for n in xrange(80000000):
- rbigint.floordiv(num, V3)
-
-
- _time = time() - t
- sumTime += _time
- print "Floordiv by 3 (not power of two):",_time
-
- t = time()
- num = rbigint.fromint(500000)
- for n in xrange(10000):
- rbigint.pow(V2, num)
-
-
- _time = time() - t
- sumTime += _time
- print "2**500000:",_time
-
- t = time()
- num = rbigint.fromint(5000000)
- for n in xrange(31):
- rbigint.pow(rbigint.pow(V2, rbigint.fromint(n)), num)
-
-
- _time = time() - t
- sumTime += _time
- print "(2**N)**5000000 (power of two):",_time
-
- t = time()
- num = rbigint.pow(rbigint.fromint(10000), rbigint.fromint(2 ** 8))
- P10_4 = rbigint.fromint(10**4)
- V100 = rbigint.fromint(100)
- for n in xrange(60000):
- rbigint.pow(P10_4, num, V100)
-
-
- _time = time() - t
- sumTime += _time
- print "10000 ** BIGNUM % 100", _time
-
- t = time()
- i = rbigint.fromint(2**31)
- i2 = rbigint.fromint(2**31)
- for n in xrange(75000):
- i = i.mul(i2)
-
- _time = time() - t
- sumTime += _time
- print "i = i * i:", _time
-
- t = time()
-
- for n in xrange(10000):
- rbigint.pow(rbigint.fromint(n), P10_4)
-
-
- _time = time() - t
- sumTime += _time
- print "n**10000 (not power of two):",_time
-
- t = time()
- for n in xrange(100000):
- rbigint.pow(V1024, V1024)
-
-
- _time = time() - t
- sumTime += _time
- print "Power of two ** power of two:", _time
-
-
- t = time()
- v = rbigint.fromint(2)
- P62 = rbigint.fromint(2**62)
- for n in xrange(50000):
- v = v.mul(P62)
-
-
- _time = time() - t
- sumTime += _time
- print "v = v * power of two", _time
-
- t = time()
- v2 = rbigint.fromint(2**8)
- for n in xrange(28):
- v2 = v2.mul(v2)
-
-
- _time = time() - t
- sumTime += _time
- print "v = v * v", _time
-
- t = time()
- v3 = rbigint.fromint(2**62)
- for n in xrange(500000):
- v3 = v3.add(v3)
-
-
- _time = time() - t
- sumTime += _time
- print "v = v + v", _time
-
- print "Sum: ", sumTime
-
- return 0
-
-# _____ Define and setup target ___
-
-def target(*args):
- return entry_point, None
-
-if __name__ == '__main__':
- import sys
- res = entry_point(sys.argv)
- sys.exit(res)
More information about the pypy-commit
mailing list