summaryrefslogtreecommitdiff
path: root/tests/run/int128.pyx
diff options
context:
space:
mode:
Diffstat (limited to 'tests/run/int128.pyx')
-rw-r--r--tests/run/int128.pyx97
1 files changed, 94 insertions, 3 deletions
diff --git a/tests/run/int128.pyx b/tests/run/int128.pyx
index cb18ccbd8..e99acf3d0 100644
--- a/tests/run/int128.pyx
+++ b/tests/run/int128.pyx
@@ -1,3 +1,4 @@
+# mode: run
cdef extern from *:
ctypedef long long int128_t "__int128_t"
@@ -60,7 +61,16 @@ def unsigned_conversion(x):
340282366920938463463374607431768211455
>>> bigint(unsigned_conversion(2**128)) # doctest: +ELLIPSIS
Traceback (most recent call last):
- OverflowError: ... too big to convert
+ OverflowError: ... to convert...
+ >>> bigint(unsigned_conversion(2**128+1)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
+ >>> bigint(unsigned_conversion(2**129-1)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
+ >>> bigint(unsigned_conversion(2**129)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
"""
cdef uint128_t n = x
return n
@@ -108,12 +118,93 @@ def signed_conversion(x):
170141183460469231731687303715884105727
>>> bigint(signed_conversion(2**127)) # doctest: +ELLIPSIS
Traceback (most recent call last):
- OverflowError: ... too big to convert
+ OverflowError: ... to convert...
+ >>> bigint(signed_conversion(-2**127+1))
+ -170141183460469231731687303715884105727
>>> bigint(signed_conversion(-2**127))
-170141183460469231731687303715884105728
>>> bigint(signed_conversion(-2**127-1)) # doctest: +ELLIPSIS
Traceback (most recent call last):
- OverflowError: ... too big to convert
+ OverflowError: ... to convert...
+ >>> bigint(signed_conversion(-2**127-2)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
+ >>> bigint(signed_conversion(-2**128+1)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
+ >>> bigint(signed_conversion(-2**128)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ OverflowError: ... to convert...
"""
cdef int128_t n = x
return n
+
+
+def get_int_distribution(shuffle=True):
+ """
+ >>> L = get_int_distribution()
+ >>> bigint(L[0])
+ 682
+ >>> bigint(L[ len(L) // 2 ])
+ 5617771410183435
+ >>> bigint(L[-1])
+ 52818775009509558395695966805
+ >>> len(L)
+ 66510
+ """
+ # Large integers that cover 1-4 (30 bits) or 1-7 (15 bits) PyLong digits.
+ # Uses only integer calculations to avoid rounding issues.
+ pow2 = [2**exp for exp in range(98)]
+ ints = [
+ n // 3
+ for i in range(11, len(pow2) - 1)
+ # Take a low but growing number of integers from each power-of-2 range.
+ for n in range(pow2[i], pow2[i+1], pow2[i - 8] - 1)
+ ]
+ return ints * 3 # longer list, but keeps median in the middle
+
+
+def intsum(L):
+ """
+ >>> L = get_int_distribution()
+ >>> bigint(intsum(L))
+ 61084913298497804284622382871263
+ >>> bigint(sum(L))
+ 61084913298497804284622382871263
+
+ >>> from random import shuffle
+ >>> shuffle(L)
+ >>> bigint(intsum(L))
+ 61084913298497804284622382871263
+ """
+ cdef uint128_t i, x = 0
+ for i in L:
+ x += i
+ return x
+
+
+def intxor(L):
+ """
+ >>> L = get_int_distribution()
+ >>> bigint(intxor(L))
+ 31773794341658093722410838161
+ >>> bigint(intxor(L * 2))
+ 0
+ >>> import operator
+ >>> from functools import reduce
+ >>> bigint(reduce(operator.xor, L))
+ 31773794341658093722410838161
+ >>> bigint(reduce(operator.xor, L * 2))
+ 0
+
+ >>> from random import shuffle
+ >>> shuffle(L)
+ >>> bigint(intxor(L))
+ 31773794341658093722410838161
+ >>> bigint(intxor(L * 2))
+ 0
+ """
+ cdef uint128_t i, x = 0
+ for i in L:
+ x ^= i
+ return x