From 3a72f95919323d7a36cb3d153d92de90d64853a1 Mon Sep 17 00:00:00 2001 From: Yoctopuce dev Date: Sun, 20 Jul 2025 16:38:33 +0200 Subject: [PATCH] py/objint_longlong: Fix longlong interoperability with floats. 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 --- py/objint_longlong.c | 17 +++++++++++++++++ tests/float/int_64_float.py | 25 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/float/int_64_float.py diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 8b8fdc62e8..1a6242b979 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -165,11 +165,28 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs_in); } else if (mp_obj_is_exact_type(rhs_in, &mp_type_int)) { rhs_val = ((mp_obj_int_t *)rhs_in)->val; + #if MICROPY_PY_BUILTINS_FLOAT + } else if (mp_obj_is_float(rhs_in)) { + return mp_obj_float_binary_op(op, (mp_float_t)lhs_val, rhs_in); + #endif + #if MICROPY_PY_BUILTINS_COMPLEX + } else if (mp_obj_is_type(rhs_in, &mp_type_complex)) { + return mp_obj_complex_binary_op(op, (mp_float_t)lhs_val, 0, rhs_in); + #endif } else { // delegate to generic function to check for extra cases return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in); } + #if MICROPY_PY_BUILTINS_FLOAT + if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) { + if (rhs_val == 0) { + goto zero_division; + } + return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); + } + #endif + switch (op) { case MP_BINARY_OP_ADD: case MP_BINARY_OP_INPLACE_ADD: diff --git a/tests/float/int_64_float.py b/tests/float/int_64_float.py new file mode 100644 index 0000000000..ffdb0c71db --- /dev/null +++ b/tests/float/int_64_float.py @@ -0,0 +1,25 @@ +# test int64 operation with float/complex + +i = 1 << 40 + +# convert int64 to float on rhs +print("%.5g" % (2.0 * i)) + +# negative int64 as float +print("%.5g" % float(-i)) + +# this should convert to float +print("%.5g" % (i / 5)) + +# these should delegate to float +print("%.5g" % (i * 1.2)) +print("%.5g" % (i / 1.2)) + +# negative power should produce float +print("%.5g" % (i**-1)) +print("%.5g" % ((2 + i - i) ** -3)) + +try: + i / 0 +except ZeroDivisionError: + print("ZeroDivisionError")