diff options
| -rw-r--r-- | py/objint.c | 2 | ||||
| -rw-r--r-- | py/parsenum.c | 9 | ||||
| -rw-r--r-- | tests/basics/int_64_basics.py | 8 |
3 files changed, 15 insertions, 4 deletions
diff --git a/py/objint.c b/py/objint.c index 87d8a2785..fd9ab106f 100644 --- a/py/objint.c +++ b/py/objint.c @@ -247,7 +247,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co char sign = '\0'; if (num < 0) { - num = -num; + num = -(fmt_uint_t)num; sign = '-'; } diff --git a/py/parsenum.c b/py/parsenum.c index e18002306..4239f2dcd 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -64,7 +64,7 @@ typedef mp_int_t parsed_int_t; typedef unsigned long long parsed_int_t; #define PARSED_INT_MUL_OVERFLOW mp_mul_ull_overflow -#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX) +#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX + 1) #endif mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) { @@ -135,8 +135,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m have_ret_val: #else // The PARSED_INT_FITS check above ensures parsed_val won't overflow signed long long - long long signed_val = parsed_val; - if (neg) { + long long signed_val = -parsed_val; + if (!neg) { + if (signed_val == LLONG_MIN) { + goto overflow; + } signed_val = -signed_val; } ret_val = mp_obj_new_int_from_ll(signed_val); // Could be large or small int diff --git a/tests/basics/int_64_basics.py b/tests/basics/int_64_basics.py index 2a161dac0..ef7679331 100644 --- a/tests/basics/int_64_basics.py +++ b/tests/basics/int_64_basics.py @@ -151,3 +151,11 @@ try: print((1 << 48) << -6) except ValueError as e: print(e) + +# Test that the most extreme 64 bit integer values all parse with int() +print(int("-9223372036854775807")) +print(int("-9223372036854775808")) +print(int("9223372036854775807")) + +# Test that the most negative 64 bit integer can be formed via arithmetic +print(-9223372036854775807-1) |
