summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--py/objint.c2
-rw-r--r--py/parsenum.c9
-rw-r--r--tests/basics/int_64_basics.py8
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)