diff --git a/tests/basics/builtin_hash.py b/tests/basics/builtin_hash.py index 76fb183044..c9731a3b59 100644 --- a/tests/basics/builtin_hash.py +++ b/tests/basics/builtin_hash.py @@ -4,6 +4,7 @@ print(hash(False)) print(hash(True)) print({():1}) # hash tuple print({1 << 66:1}) # hash big int +print({-(1 << 66):2}) # hash negative big int print(hash in {hash:1}) # hash function try: diff --git a/tests/basics/int_big_error.py b/tests/basics/int_big_error.py index 62ab936f96..b7875ee87b 100644 --- a/tests/basics/int_big_error.py +++ b/tests/basics/int_big_error.py @@ -16,3 +16,16 @@ try: 1 in i except TypeError: print("TypeError") + +# overflow because rhs of >> is being converted to machine int +try: + 1 >> i +except OverflowError: + print('OverflowError') + +# to test conversion of negative mpz to machine int +# (we know << will convert to machine int, even though it fails to do the shift) +try: + i << (-(i >> 40)) +except ValueError: + print('ValueError') diff --git a/tests/basics/int_big_lshift.py b/tests/basics/int_big_lshift.py index af1d97504c..14db90bff3 100644 --- a/tests/basics/int_big_lshift.py +++ b/tests/basics/int_big_lshift.py @@ -15,3 +15,6 @@ for i in range(8): print(-100000000000000000000000000002 >> i) print(-100000000000000000000000000003 >> i) print(-100000000000000000000000000004 >> i) + +# shl by zero +print((1<<70) << 0) diff --git a/tests/basics/int_big_pow.py b/tests/basics/int_big_pow.py new file mode 100644 index 0000000000..0f75e3150b --- /dev/null +++ b/tests/basics/int_big_pow.py @@ -0,0 +1,8 @@ +# test bignum power + +i = 1 << 65 + +print(0 ** i) +print(i ** 0) +print(i ** 1) +print(i ** 2) diff --git a/tests/basics/int_big_rshift.py b/tests/basics/int_big_rshift.py index d11f8f63eb..6055e95b97 100644 --- a/tests/basics/int_big_rshift.py +++ b/tests/basics/int_big_rshift.py @@ -1,3 +1,6 @@ i = 123456789012345678901234567890 print(i >> 1) print(i >> 1000) + +# result needs rounding up +print(-(1<<70) >> 80) diff --git a/tests/basics/struct1.py b/tests/basics/struct1.py index 686251c446..1a32c482c4 100644 --- a/tests/basics/struct1.py +++ b/tests/basics/struct1.py @@ -35,8 +35,11 @@ print(struct.pack("Q", 2**64 - 1)) print(struct.pack("Q", 0xffffffffffffffff)) print(struct.pack("q", -1)) print(struct.pack("Q", 1234567890123456789)) diff --git a/tests/float/int_big_float.py b/tests/float/int_big_float.py index 5b8aaa8782..2c404189cb 100644 --- a/tests/float/int_big_float.py +++ b/tests/float/int_big_float.py @@ -5,6 +5,9 @@ i = 1 << 65 # convert bignum to float on rhs print("%.5g" % (2.0 * i)) +# negative bignum as float +print("%.5g" % float(-i)) + # this should convert to float print("%.5g" % (i / 5)) diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 00ddf0daf2..38aa22112d 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -27,3 +27,8 @@ ementation (start=1, stop=2, step=3) # str 1 +# mpz +1 +12345678 +0 +0 diff --git a/unix/coverage.c b/unix/coverage.c index 1f52d9cf82..d6514b9cff 100644 --- a/unix/coverage.c +++ b/unix/coverage.c @@ -3,6 +3,7 @@ #include "py/obj.h" #include "py/runtime.h" #include "py/repl.h" +#include "py/mpz.h" #if defined(MICROPY_UNIX_COVERAGE) @@ -83,6 +84,29 @@ STATIC mp_obj_t extra_coverage(void) { printf("%d\n", MP_OBJ_IS_QSTR(mp_obj_str_intern(mp_obj_new_str("intern me", 9, false)))); } + // mpz + { + printf("# mpz\n"); + + mp_uint_t value; + mpz_t mpz; + mpz_init_zero(&mpz); + + // mpz_as_uint_checked, with success + mpz_set_from_int(&mpz, 12345678); + printf("%d\n", mpz_as_uint_checked(&mpz, &value)); + printf("%d\n", (int)value); + + // mpz_as_uint_checked, with negative arg + mpz_set_from_int(&mpz, -1); + printf("%d\n", mpz_as_uint_checked(&mpz, &value)); + + // mpz_as_uint_checked, with overflowing arg + mpz_set_from_int(&mpz, 1); + mpz_shl_inpl(&mpz, &mpz, 70); + printf("%d\n", mpz_as_uint_checked(&mpz, &value)); + } + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_0(extra_coverage_obj, extra_coverage);