From d4b75f6b6822885e331c69a74e56e23af40a6264 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 4 Sep 2017 14:16:27 +1000 Subject: py/obj: Fix comparison of float/complex NaN with itself. IEEE floating point is specified such that a comparison of NaN with itself returns false, and Python respects these semantics. This patch makes uPy also have these semantics. The fix has a minor impact on the speed of the object-equality fast-path, but that seems to be unavoidable and it's much more important to have correct behaviour (especially in this case where the wrong answer for nan==nan is silently returned). --- tests/float/complex1.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests/float/complex1.py') diff --git a/tests/float/complex1.py b/tests/float/complex1.py index a6038de04..7f0b317b3 100644 --- a/tests/float/complex1.py +++ b/tests/float/complex1.py @@ -37,6 +37,11 @@ ans = 1j ** 2.5j; print("%.5g %.5g" % (ans.real, ans.imag)) print(1j == 1) print(1j == 1j) +# comparison of nan is special +nan = float('nan') * 1j +print(nan == 1j) +print(nan == nan) + # builtin abs print(abs(1j)) print("%.5g" % abs(1j + 2)) -- cgit v1.2.3 From bdc6e86e079dd8a82e9ead1d4041c2e17c882437 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 26 Sep 2017 12:57:51 +1000 Subject: py/objfloat: Support raising a negative number to a fractional power. This returns a complex number, following CPython behaviour. For ports that don't have complex numbers enabled this will raise a ValueError which gives a fail-safe for scripts that were written assuming complex numbers exist. --- py/objfloat.c | 7 +++++++ tests/float/complex1.py | 4 ++++ 2 files changed, 11 insertions(+) (limited to 'tests/float/complex1.py') diff --git a/py/objfloat.c b/py/objfloat.c index 55a9379ff..0831be3fd 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -298,6 +298,13 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t if (lhs_val == 0 && rhs_val < 0) { goto zero_division_error; } + if (lhs_val < 0 && rhs_val != MICROPY_FLOAT_C_FUN(floor)(rhs_val)) { + #if MICROPY_PY_BUILTINS_COMPLEX + return mp_obj_complex_binary_op(MP_BINARY_OP_POWER, lhs_val, 0, rhs_in); + #else + mp_raise_ValueError("complex values not supported"); + #endif + } lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val); break; case MP_BINARY_OP_DIVMOD: { diff --git a/tests/float/complex1.py b/tests/float/complex1.py index 7f0b317b3..854410545 100644 --- a/tests/float/complex1.py +++ b/tests/float/complex1.py @@ -53,6 +53,10 @@ print(type(hash(1j))) # float on lhs should delegate to complex print(1.2 + 3j) +# negative base and fractional power should create a complex +ans = (-1) ** 2.3; print("%.5g %.5g" % (ans.real, ans.imag)) +ans = (-1.2) ** -3.4; print("%.5g %.5g" % (ans.real, ans.imag)) + # check printing of inf/nan print(float('nan') * 1j) print(float('inf') * (1 + 1j)) -- cgit v1.2.3