summaryrefslogtreecommitdiff
path: root/py/objint_longlong.c
AgeCommit message (Collapse)Author
2025-07-29py/objint_longlong: Fix longlong interoperability with floats.Yoctopuce dev
Current longlong implementation does not allow a float as RHS of mathematic operators, as it lacks the delegation code present in mpz. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
2025-07-29py/objint_longlong: Fix overflow check in mp_obj_int_get_checked.Yoctopuce dev
This is to fix an outstanding TODO. The test cases is using a range as this will exist in all builds, but `mp_obj_get_int` is used in many different parts of code where an overflow is more likely to occur. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
2025-07-24py/objint_longlong: Fix left shift of negative values.Angus Gratton
Previous comment was wrong, left shifting a negative value is UB in C. Use the same approach as small int shifts (from runtime.c). Signed-off-by: Angus Gratton <angus@redyak.com.au>
2025-07-18py/parsenum: Extend mp_parse_num_integer() to parse long long.Angus Gratton
If big integer support is 'long long' then mp_parse_num_integer() can parse to it directly instead of failing over from small int. This means strtoll() is no longer pulled in, and fixes some bugs parsing long long integers (i.e. can now parse negative values correctly, can now parse values which aren't NULL terminated). The (default) smallint parsing compiled code should stay the same here, macros and a typedef are used to abstract some parts of it out. When bigint is long long we parse to 'unsigned long long' first (to avoid the code size hit of pulling in signed 64-bit math routines) and the convert to signed at the end. One tricky case this routine correctly overflows on is int("9223372036854775808") which is one more than LLONG_MAX in decimal. No unit test case added for this as it's too hard to detect 64-bit long integer mode. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2025-07-18py/objint_longlong: Add arithmetic overflow checks.Angus Gratton
Long long big integer support now raises an exception on overflow rather than returning an undefined result. Also adds an error when shifting by a negative value. The new arithmetic checks are added in the misc.h header. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2025-07-09py/obj: Add functions to retrieve large integers from mp_obj_t.Yoctopuce dev
This commit provides helpers to retrieve integer values from mp_obj_t when the content does not fit in a 32 bits integer, without risking an implicit wrap due to an int overflow. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
2024-07-01py/objint: Try to convert big-int back to small-int after binary op.Jim Mussared
Before this change, long/mpz ints propagated into all future calculations, even if their value could fit in a small-int object. With this change, the result of a big-int binary op will now be converted to a small-int object if the value fits in a small-int. For example, a relatively common operation like `x = a * b // c` where a,b,c all small ints would always result in a long/mpz int, even if it didn't need to, and then this would impact all future calculations with x. This adds +24 bytes on PYBV11 but avoids heap allocations and potential surprises (e.g. `big-big` is now a small `0`, and can safely be accessed with MP_OBJ_SMALL_INT_VALUE). Performance tests are unchanged on PYBV10, except for `bm_pidigits.py` which makes heavy use of big-ints and gains about 8% in speed. Unix coverage tests have been updated to cover mpz code that is now unreachable by normal Python code (removing the unreachable code would lead to some surprising gaps in the internal C functions and the functionality may be needed in the future, so it is kept because it has minimal overhead). This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2024-06-24py/objint: Fix int.to_bytes() buffer size checks.Angus Gratton
Fixes and improvements to `int.to_bytes()` are: - No longer overflows if byte size is 0 (closes #13041). - Raises OverflowError in any case where number won't fit into byte length (now matches CPython, previously MicroPython would return a truncated bytes object). - Document that `micropython int.to_bytes()` doesn't implement the optional signed kwarg, but will behave as if `signed=True` when the integer is negative (this is the current behaviour). Add tests for this also. Requires changes for small ints, MPZ large ints, and "long long" large ints. Adds a new set of unit tests for ints between 32 and 64 bits to increase coverage of "long long" large ints, which are otherwise untested. Tested on unix port (64 bit small ints, MPZ long ints) and Zephyr STM32WB board (32 bit small ints, long long large ints). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2023-06-01py: Change MP_UNARY_OP_INT to MP_UNARY_OP_INT_MAYBE.Damien George
To be consistent with MP_UNARY_OP_INT_FLOAT and MP_UNARY_OP_INT_COMPLEX, and allow int() to first check if a type supports __int__ before trying other things (as per CPython). Signed-off-by: Damien George <damien@micropython.org>
2022-07-18py/obj: Add static safety checks to mp_obj_is_type().Yonatan Goldschmidt
Commit d96cfd13e3a464862c introduced a regression by breaking existing users of mp_obj_is_type(.., &mp_obj_bool). This function (and associated helpers like mp_obj_is_int()) have some specific nuances, and mistakes like this one can happen again. This commit adds mp_obj_is_exact_type() which behaves like the the old mp_obj_is_type(). The new mp_obj_is_type() has the same prototype but it attempts to statically assert that it's not called with types which should be checked using mp_obj_is_type(). If called with any of these types: int, str, bool, NoneType - it will cause a compilation error. Additional checked types (e.g function types) can be added in the future. Existing users of mp_obj_is_type() with the now "invalid" types, were translated to use mp_obj_is_exact_type(). The use of MP_STATIC_ASSERT() is not bulletproof - usually GCC (and other compilers) can't statically check conditions that are only known during link-time (like variables' addresses comparison). However, in this case, GCC is able to statically detect these conditions, probably because it's the exact same object - `&mp_type_int == &mp_type_int` is detected. Misuses of this function with runtime-chosen types (e.g: `mp_obj_type_t *x = ...; mp_obj_is_type(..., x);` won't be detected. MSC is unable to detect this, so we use MP_STATIC_ASSERT_NOT_MSC(). Compiling with this commit and without the fix for d96cfd13e3a464862c shows that it detects the problem. Signed-off-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
2022-05-03all: Use mp_obj_malloc everywhere it's applicable.Jim Mussared
This replaces occurences of foo_t *foo = m_new_obj(foo_t); foo->base.type = &foo_type; with foo_t *foo = mp_obj_malloc(foo_t, &foo_type); Excludes any places where base is a sub-field or when new0/memset is used. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2020-05-28py/modsys: Use consistent naming pattern for module-level const objects.David Lechner
This renames a few identifiers to follow the usual naming convention of mp_<module>_<name>. This makes them easier to find, e.g. when grep'ing.
2020-04-05all: Use MP_ERROR_TEXT for all error messages.Jim Mussared
2020-02-28all: Reformat C and Python source code with tools/codeformat.py.Damien George
This is run with uncrustify 0.70.1, and black 19.10b0.
2019-02-12py: Downcase all MP_OBJ_IS_xxx macros to make a more consistent C API.Damien George
These macros could in principle be (inline) functions so it makes sense to have them lower case, to match the other C API functions. The remaining macros that are upper case are: - MP_OBJ_TO_PTR, MP_OBJ_FROM_PTR - MP_OBJ_NEW_SMALL_INT, MP_OBJ_SMALL_INT_VALUE - MP_OBJ_NEW_QSTR, MP_OBJ_QSTR_VALUE - MP_OBJ_FUN_MAKE_SIG - MP_DECLARE_CONST_xxx - MP_DEFINE_CONST_xxx These must remain macros because they are used when defining const data (at least, MP_OBJ_NEW_SMALL_INT is so it makes sense to have MP_OBJ_SMALL_INT_VALUE also a macro). For those macros that have been made lower case, compatibility macros are provided for the old names so that users do not need to change their code immediately.
2018-09-20py: Shorten error messages by using contractions and some rewording.Damien George
2018-04-05py/objint: Simplify LHS arg type checking in int binary op functions.Damien George
The LHS passed to mp_obj_int_binary_op() will always be an integer, either a small int or a big int, so the test for this type doesn't need to include an "other, unsupported type" case.
2017-12-08py/objint_longlong: Check for zero division/modulo.Paul Sokolovsky
2017-10-04all: Remove inclusion of internal py header files.Damien George
Header files that are considered internal to the py core and should not normally be included directly are: py/nlr.h - internal nlr configuration and declarations py/bc0.h - contains bytecode macro definitions py/runtime0.h - contains basic runtime enums Instead, the top-level header files to include are one of: py/obj.h - includes runtime0.h and defines everything to use the mp_obj_t type py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h, and defines everything to use the general runtime support functions Additional, specific headers (eg py/objlist.h) can be included if needed.
2017-09-18py/modbuiltins: Implement abs() by dispatching to MP_UNARY_OP_ABS.Paul Sokolovsky
This allows user classes to implement __abs__ special method, and saves code size (104 bytes for x86_64), even though during refactor, an issue was fixed and few optimizations were made: * abs() of minimum (negative) small int value is calculated properly. * objint_longlong and objint_mpz avoid allocating new object is the argument is already non-negative.
2017-08-29all: Convert mp_uint_t to mp_unary_op_t/mp_binary_op_t where appropriateDamien George
The unary-op/binary-op enums are already defined, and there are no arithmetic tricks used with these types, so it makes sense to use the correct enum type for arguments that take these values. It also reduces code size quite a bit for nan-boxing builds.
2017-07-31all: Use the name MicroPython consistently in commentsAlexander Steffen
There were several different spellings of MicroPython present in comments, when there should be only one.
2017-07-25py: Implement raising a big-int to a negative power.Damien George
Before this patch raising a big-int to a negative power would just return 0. Now it returns a floating-point number with the correct value.
2017-06-15all: Make more use of mp_raise_{msg,TypeError,ValueError} helpers.Damien George
2017-04-30py: Cleanup use of global DEBUG preprocessor definitionstijn
The standard preprocessor definition to differentiate debug and non-debug builds is NDEBUG, not DEBUG, so don't rely on the latter: - just delete the use of it in objint_longlong.c as it has been stale code for years anyway (since commit [c4029e5]): SUFFIX isn't used anywhere. - replace DEBUG with MICROPY_DEBUG_NLR in nlr.h: it is rarely used anymore so can be off by default
2017-04-04py/objint: Consolidate mp_obj_new_int_from_float to one implementation.Damien George
This reduces code duplication and allows to make mp_classify_fp_as_int static, which reduces code size.
2017-03-10py/objint_longlong: Implement mp_obj_int_from_bytes_impl().Paul Sokolovsky
This makes int.from_bytes() work for MICROPY_LONGINT_IMPL_LONGLONG.
2017-02-16py/objint: Convert mp_uint_t to size_t where appropriate.Damien George
2017-01-21py/objint_longlong: Add stub for mp_obj_int_from_bytes_impl().Paul Sokolovsky
To be implemented later.
2016-12-21py/objint: Rename mp_obj_int_as_float to mp_obj_int_as_float_impl.Damien George
And also simplify it to remove the check for small int. This can be done because this function is only ever called if the argument is not a small int.
2016-10-11py/objint: Use size_t for arguments that measure bytes/sizes.Damien George
2016-03-10py: Use MP_SMALL_INT_POSITIVE_MASK to check if uint fits in a small int.Damien George
Using the original WORD_MSBIT_HIGH-logic resulted in errors when the object model is not REPR_A or REPR_C.
2016-01-07py: Change mp_obj_int_is_positive to more general mp_obj_int_sign.Damien George
This function returns the sign (-1, 0 or 1) of the integer object.
2015-11-09py/objint_longlong: Instead of assert, throw OverflowError.Paul Sokolovsky
2015-10-11py: Rename MP_BOOL() to mp_obj_new_bool() for consistency in naming.Paul Sokolovsky
2015-05-12py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function.Damien George
Hashing is now done using mp_unary_op function with MP_UNARY_OP_HASH as the operator argument. Hashing for int, str and bytes still go via fast-path in mp_unary_op since they are the most common objects which need to be hashed. This lead to quite a bit of code cleanup, and should be more efficient if anything. It saves 176 bytes code space on Thumb2, and 360 bytes on x86. The only loss is that the error message "unhashable type" is now the more generic "unsupported type for __hash__".
2015-04-25py: Implement power op for long-long implementation of bignum.Damien George
2015-04-25py: Support conversion of bignum to bytes.Damien George
This gets int.to_bytes working for bignum, and also struct.pack with 'q' and 'Q' args on 32-bit machines. Addresses issue #1155.
2015-03-14py: Fix builtin abs so it works for bools and bignum.Damien George
2015-01-24py: Use float-to-int classifications for mp_obj_new_int_from_float() functionsDavid Steinberg
2015-01-01py: Move to guarded includes, everywhere in py/ core.Damien George
Addresses issue #1022.
2014-12-30py: Partially fix float to int conversion.Paul Sokolovsky
This fixes conversion when float type has more mantissa bits than small int, and float value has small exponent. This is for example the case of 32-bit platform using doubles, and converting value of time.time(). Conversion of floats with larg exponnet is still not handled correctly.
2014-12-05py: Rename mp_obj_int_get to mp_obj_int_get_truncated; fix struct.pack.Damien George
mp_obj_int_get_truncated is used as a "fast path" int accessor that doesn't check for overflow and returns the int truncated to the machine word size, ie mp_int_t. Use mp_obj_int_get_truncated to fix struct.pack when packing maximum word sized values. Addresses issues #779 and #998.
2014-09-10py: Enable struct/binary-helper to parse q and Q sized ints.Damien George
Addresses issue #848.
2014-09-06py: Correctly set sys.maxsize value for 64-bit.Paul Sokolovsky
Type representing signed size doesn't have to be int, so use special value which defaults to SSIZE_MAX, but as it's not defined by C standard (but rather by POSIX), allow ports to set it.
2014-08-30Change some parts of the core API to use mp_uint_t instead of uint/int.Damien George
Addressing issue #50, still some way to go yet.
2014-07-24py: Make long ints hashable.Damien George
Addresses issue #765.
2014-07-03py: Implement sys.maxsize, standard way to check platform "bitness".Paul Sokolovsky
Implementing it as a static constant is a bit peculiar and require cooperation from long int implementation.
2014-07-03Rename machine_(u)int_t to mp_(u)int_t.Damien George
See discussion in issue #50.
2014-06-01Rename bultins config variables to MICROPY_PY_BUILTINS_*.Damien George
This renames: MICROPY_PY_FROZENSET -> MICROPY_PY_BUILTINS_FROZENSET MICROPY_PY_PROPERTY -> MICROPY_PY_BUILTINS_PROPERTY MICROPY_PY_SLICE -> MICROPY_PY_BUILTINS_SLICE MICROPY_ENABLE_FLOAT -> MICROPY_PY_BUILTINS_FLOAT See issue #35 for discussion.