|
11 | 11 | from rpython.rlib import rbigint as lobj |
12 | 12 | from rpython.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, intmask |
13 | 13 | from rpython.rlib.rbigint import (rbigint, SHIFT, MASK, KARATSUBA_CUTOFF, |
14 | | - _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError) |
| 14 | + _store_digit, _mask_digit, InvalidEndiannessError, InvalidSignednessError, |
| 15 | + gcd_lehmer, lehmer_xgcd, gcd_binary) |
15 | 16 | from rpython.rlib.rfloat import NAN |
16 | 17 | from rpython.rtyper.test.test_llinterp import interpret |
17 | 18 | from rpython.translator.c.test.test_standalone import StandaloneTests |
18 | 19 |
|
19 | | -from hypothesis import given, strategies, example |
| 20 | +from hypothesis import given, strategies, example, settings |
20 | 21 |
|
21 | 22 | longs = strategies.builds( |
22 | 23 | long, strategies.integers()) |
@@ -836,6 +837,27 @@ def test_frombytes_tobytes_hypothesis(self, s, big, signed): |
836 | 837 | t = bigint.tobytes(len(s), byteorder=byteorder, signed=signed) |
837 | 838 | assert s == t |
838 | 839 |
|
| 840 | + def test_gcd(self): |
| 841 | + assert gcd_binary(2*3*7**2, 2**2*7) == 2*7 |
| 842 | + pytest.raises(ValueError, gcd_binary, 2*3*7**2, -2**2*7) |
| 843 | + assert gcd_binary(1234, 5678) == 2 |
| 844 | + assert gcd_binary(13, 13**6) == 13 |
| 845 | + assert gcd_binary(12, 0) == 12 |
| 846 | + assert gcd_binary(0, 0) == 0 |
| 847 | + assert pytest.raises(ValueError, gcd_binary, -10, 0) |
| 848 | + assert pytest.raises(ValueError, gcd_binary, 10, -10) |
| 849 | + |
| 850 | + x = rbigint.fromlong(9969216677189303386214405760200) |
| 851 | + y = rbigint.fromlong(16130531424904581415797907386349) |
| 852 | + g = x.gcd(y) |
| 853 | + assert g == rbigint.fromlong(1) |
| 854 | + |
| 855 | + for x in gen_signs([12843440367927679363613699686751681643652809878241019930204617606850071260822269719878805]): |
| 856 | + x = rbigint.fromlong(x) |
| 857 | + for y in gen_signs([12372280584571061381380725743231391746505148712246738812788540537514927882776203827701778968535]): |
| 858 | + y = rbigint.fromlong(y) |
| 859 | + g = x.gcd(y) |
| 860 | + assert g.tolong() == 18218089570126697993340888567155155527541105 |
839 | 861 |
|
840 | 862 |
|
841 | 863 | class TestInternalFunctions(object): |
@@ -1255,3 +1277,52 @@ def test_int_comparison(self, x, y): |
1255 | 1277 | assert lx.lt(ly) == (x < y) |
1256 | 1278 | assert lx.eq(ly) == (x == y) |
1257 | 1279 | assert lx.le(ly) == (x <= y) |
| 1280 | + |
| 1281 | + @given(ints, ints, ints) |
| 1282 | + def test_gcd_binary(self, x, y, z): |
| 1283 | + x, y, z = abs(x), abs(y), abs(z) |
| 1284 | + |
| 1285 | + def test(a, b, res): |
| 1286 | + g = gcd_binary(a, b) |
| 1287 | + |
| 1288 | + assert g == res |
| 1289 | + |
| 1290 | + a, b = x, y |
| 1291 | + while b: |
| 1292 | + a, b = b, a % b |
| 1293 | + |
| 1294 | + gcd_x_y = a |
| 1295 | + |
| 1296 | + test(x, y, gcd_x_y) |
| 1297 | + test(x, 0, x) |
| 1298 | + test(0, x, x) |
| 1299 | + test(x * z, y * z, gcd_x_y * z) |
| 1300 | + test(x * z, z, z) |
| 1301 | + test(z, y * z, z) |
| 1302 | + |
| 1303 | + @given(biglongs, biglongs, biglongs) |
| 1304 | + @example(112233445566778899112233445566778899112233445566778899, |
| 1305 | + 13579246801357924680135792468013579246801, |
| 1306 | + 99887766554433221113) |
| 1307 | + @settings(max_examples=10) |
| 1308 | + def test_gcd(self, x, y, z): |
| 1309 | + print(x, y, z) |
| 1310 | + x, y, z = abs(x), abs(y), abs(z) |
| 1311 | + |
| 1312 | + def test(a, b, res): |
| 1313 | + g = rbigint.fromlong(a).gcd(rbigint.fromlong(b)).tolong() |
| 1314 | + |
| 1315 | + assert g == res |
| 1316 | + |
| 1317 | + a, b = x, y |
| 1318 | + while b: |
| 1319 | + a, b = b, a % b |
| 1320 | + |
| 1321 | + gcd_x_y = a |
| 1322 | + |
| 1323 | + test(x, y, gcd_x_y) |
| 1324 | + test(x * z, y * z, gcd_x_y * z) |
| 1325 | + test(x * z, z, z) |
| 1326 | + test(z, y * z, z) |
| 1327 | + test(x, 0, x) |
| 1328 | + test(0, x, x) |
0 commit comments