From 21c5be3706f70d573f8d0195760846fce46f6807 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Tue, 6 Feb 2024 16:45:04 +0300 Subject: fixed the power (^*) operator: did not handle corner cases and was inefficient * in fact, with a negative exponent the previous naive implementation would even hang indefinitely! * Now uses the squaring algorithm. This is slightly longer but significantly more efficient. * added test cases --- src/expressions.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/expressions.c') diff --git a/src/expressions.c b/src/expressions.c index 93e3fdc..cec3492 100644 --- a/src/expressions.c +++ b/src/expressions.c @@ -184,7 +184,28 @@ teco_expressions_calc(GError **error) switch (op) { case TECO_OP_POW: - for (result = 1; vright--; result *= vleft); + if (!vright) { + result = vleft < 0 ? -1 : 1; + break; + } + if (vright < 0) { + if (!vleft) { + g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, + "Negative power of 0 is not defined"); + return FALSE; + } + result = ABS(vleft) == 1 ? vleft : 0; + break; + } + result = 1; + for (;;) { + if (vright & 1) + result *= vleft; + vright >>= 1; + if (!vright) + break; + vleft *= vleft; + } break; case TECO_OP_MUL: result = vleft * vright; -- cgit v1.2.3