[pypy-commit] pypy default: port the new tests from math-improvements to default
cfbolz
pypy.commits at gmail.com
Thu Dec 13 13:56:55 EST 2018
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch:
Changeset: r95477:bbea6977d260
Date: 2018-12-13 19:53 +0100
http://bitbucket.org/pypy/pypy/changeset/bbea6977d260/
Log: port the new tests from math-improvements to default
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
@@ -6,6 +6,7 @@
from random import random, randint, sample, seed
import py
+import pytest
from rpython.rlib import rbigint as lobj
from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask
@@ -15,7 +16,21 @@
from rpython.rtyper.test.test_llinterp import interpret
from rpython.translator.c.test.test_standalone import StandaloneTests
-from hypothesis import given, strategies
+from hypothesis import given, strategies, example
+
+longs = strategies.builds(
+ long, strategies.integers())
+ints = strategies.integers(-sys.maxint-1, sys.maxint)
+
+def makelong(data):
+ numbits = data.draw(strategies.integers(1, 2000))
+ r = data.draw(strategies.integers(0, 1 << numbits))
+ if data.draw(strategies.booleans()):
+ return -r
+ return r
+
+biglongs = strategies.builds(makelong, strategies.data())
+
def gen_signs(l):
for s in l:
@@ -44,8 +59,8 @@
class TestRLong(object):
def test_simple(self):
- for op1 in [-2, -1, 0, 1, 2, 50]:
- for op2 in [-2, -1, 0, 1, 2, 50]:
+ for op1 in [-2, -1, 0, 1, 2, 10, 50]:
+ for op2 in [-2, -1, 0, 1, 2, 10, 50]:
rl_op1 = rbigint.fromint(op1)
rl_op2 = rbigint.fromint(op2)
for op in "add sub mul".split():
@@ -155,13 +170,25 @@
def test_pow(self):
for op1 in gen_signs(long_vals_not_too_big):
+ rl_op1 = rbigint.fromlong(op1)
for op2 in [0, 1, 2, 8, 9, 10, 11]:
- rl_op1 = rbigint.fromlong(op1)
rl_op2 = rbigint.fromint(op2)
r1 = rl_op1.pow(rl_op2)
r2 = op1 ** op2
assert r1.tolong() == r2
+ for op3 in gen_signs([1, 2, 5, 1000, 12312312312312235659969696l]):
+ if not op3:
+ continue
+ print op1, op2, op3
+ r3 = rl_op1.pow(rl_op2, rbigint.fromlong(op3))
+ r4 = pow(op1, op2, op3)
+ assert r3.tolong() == r4
+
+ def test_pow_raises(self):
+ r1 = rbigint.fromint(2)
+ r0 = rbigint.fromint(0)
+ py.test.raises(ValueError, r1.pow, r1, r0)
def test_touint(self):
result = r_uint(sys.maxint + 42)
@@ -503,20 +530,6 @@
f1, f2, f3 = [rbigint.fromlong(i)
for i in (10L, 5L, 0L)]
py.test.raises(ValueError, f1.pow, f2, f3)
- #
- MAX = 1E20
- x = long(random() * MAX) + 1
- y = long(random() * MAX) + 1
- z = long(random() * MAX) + 1
- f1 = rbigint.fromlong(x)
- f2 = rbigint.fromlong(y)
- f3 = rbigint.fromlong(z)
- print f1
- print f2
- print f3
- v = f1.pow(f2, f3)
- print '--->', v
- assert v.tolong() == pow(x, y, z)
def test_pow_lll_bug(self):
two = rbigint.fromint(2)
@@ -585,6 +598,24 @@
res3 = f1.abs_rshift_and_mask(r_ulonglong(y), mask)
assert res3 == (abs(x) >> y) & mask
+ # test special optimization case in rshift:
+ assert rbigint.fromlong(-(1 << 100)).rshift(5).tolong() == -(1 << 100) >> 5
+
+ def test_qshift(self):
+ for x in range(10):
+ for y in range(1, 161, 16):
+ num = (x << y) + x
+ f1 = rbigint.fromlong(num)
+ nf1 = rbigint.fromlong(-num)
+
+ for z in range(1, 31):
+ res1 = f1.lqshift(z).tolong()
+ res3 = nf1.lqshift(z).tolong()
+
+ assert res1 == num << z
+ assert res3 == -num << z
+
+
def test_from_list_n_bits(self):
for x in ([3L ** 30L, 5L ** 20L, 7 ** 300] +
[1L << i for i in range(130)] +
@@ -674,19 +705,12 @@
def test_hash(self):
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
sys.maxint-3, sys.maxint-2, sys.maxint-1, sys.maxint,
- ] + [randint(0, sys.maxint) for _ in range(100)]:
+ ]:
# hash of machine-sized integers
assert rbigint.fromint(i).hash() == i
# hash of negative machine-sized integers
assert rbigint.fromint(-i-1).hash() == -i-1
#
- for i in range(200):
- # hash of large integers: should be equal to the hash of the
- # integer reduced modulo 2**64-1, to make decimal.py happy
- x = randint(0, sys.maxint**5)
- y = x % (2**64-1)
- assert rbigint.fromlong(x).hash() == rbigint.fromlong(y).hash()
- assert rbigint.fromlong(-x).hash() == rbigint.fromlong(-y).hash()
def test_log(self):
from rpython.rlib.rfloat import ulps_check
@@ -756,6 +780,7 @@
f1 = rbigint.fromlong(x)
f2 = y
remainder = lobj._inplace_divrem1(f1, f1, f2)
+ f1._normalize()
assert (f1.tolong(), remainder) == divmod(x, y)
out = bigint([99, 99], 1)
remainder = lobj._inplace_divrem1(out, out, 100)
@@ -787,7 +812,7 @@
y += randint(1, 1 << 60)
if y > x:
x <<= 100
-
+
f1 = rbigint.fromlong(x)
f2 = rbigint.fromlong(y)
div, rem = lobj._x_divrem(f1, f2)
@@ -827,6 +852,18 @@
assert rem.tolong() == _rem
py.test.raises(ZeroDivisionError, rbigint.fromlong(x).divmod, rbigint.fromlong(0))
+ # an explicit example for a very rare case in _x_divrem:
+ # "add w back if q was too large (this branch taken rarely)"
+ x = 2401064762424988628303678384283622960038813848808995811101817752058392725584695633
+ y = 510439143470502793407446782273075179624699774495710665331026
+ f1 = rbigint.fromlong(x)
+ f2 = rbigint.fromlong(y)
+ div, rem = f1.divmod(f2)
+ _div, _rem = divmod(x, y)
+ assert div.tolong() == _div
+ assert rem.tolong() == _rem
+
+
# testing Karatsuba stuff
def test__v_iadd(self):
f1 = bigint([lobj.MASK] * 10, 1)
@@ -858,14 +895,6 @@
ret = lobj._k_mul(f1, f2)
assert ret.tolong() == f1.tolong() * f2.tolong()
- def test__k_lopsided_mul(self):
- digs_a = KARATSUBA_CUTOFF + 3
- digs_b = 3 * digs_a
- f1 = bigint([lobj.MASK] * digs_a, 1)
- f2 = bigint([lobj.MASK] * digs_b, 1)
- ret = lobj._k_lopsided_mul(f1, f2)
- assert ret.tolong() == f1.tolong() * f2.tolong()
-
def test_longlong(self):
max = 1L << (r_longlong.BITS-1)
f1 = rbigint.fromlong(max-1) # fits in r_longlong
@@ -1026,3 +1055,73 @@
t, cbuilder = self.compile(entry_point)
data = cbuilder.cmdexec('hi there')
assert data == '[%d]\n[0, 1]\n' % sys.maxint
+
+class TestHypothesis(object):
+ @given(longs, longs, longs)
+ def test_pow(self, x, y, z):
+ f1 = rbigint.fromlong(x)
+ f2 = rbigint.fromlong(y)
+ f3 = rbigint.fromlong(z)
+ try:
+ res = pow(x, y, z)
+ except Exception as e:
+ pytest.raises(type(e), f1.pow, f2, f3)
+ else:
+ v = f1.pow(f2, f3)
+ assert v.tolong() == res
+
+ @given(biglongs, biglongs)
+ @example(510439143470502793407446782273075179618477362188870662225920,
+ 108089693021945158982483698831267549521)
+ def test_divmod(self, x, y):
+ if x < y:
+ x, y = y, x
+
+ f1 = rbigint.fromlong(x)
+ f2 = rbigint.fromlong(y)
+ try:
+ res = divmod(x, y)
+ except Exception as e:
+ pytest.raises(type(e), f1.divmod, f2)
+ else:
+ print x, y
+ a, b = f1.divmod(f2)
+ assert (a.tolong(), b.tolong()) == res
+
+ @given(longs)
+ def test_hash(self, x):
+ # hash of large integers: should be equal to the hash of the
+ # integer reduced modulo 2**64-1, to make decimal.py happy
+ x = randint(0, sys.maxint**5)
+ y = x % (2**64-1)
+ assert rbigint.fromlong(x).hash() == rbigint.fromlong(y).hash()
+ assert rbigint.fromlong(-x).hash() == rbigint.fromlong(-y).hash()
+
+ @given(ints)
+ def test_hash_int(self, x):
+ # hash of machine-sized integers
+ assert rbigint.fromint(x).hash() == x
+ # hash of negative machine-sized integers
+ assert rbigint.fromint(-x-1).hash() == -x-1
+
+ @given(longs)
+ def test_abs(self, x):
+ assert rbigint.fromlong(x).abs().tolong() == abs(x)
+
+ @given(longs, longs)
+ def test_truediv(self, a, b):
+ ra = rbigint.fromlong(a)
+ rb = rbigint.fromlong(b)
+ if not b:
+ pytest.raises(ZeroDivisionError, ra.truediv, rb)
+ else:
+ assert ra.truediv(rb) == a / b
+
+ @given(longs, longs)
+ def test_bitwise(self, x, y):
+ lx = rbigint.fromlong(x)
+ ly = rbigint.fromlong(y)
+ for mod in "xor and_ or_".split():
+ res1 = getattr(lx, mod)(ly).tolong()
+ res2 = getattr(operator, mod)(x, y)
+ assert res1 == res2
More information about the pypy-commit
mailing list