From 151e6f79f1941b01135df73f0fc5c0d53ae0b3c9 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 26 Aug 2024 12:56:33 -0700 Subject: [PATCH] replace pxt_powi implementation with better one (#1484) * replace pxt_powi implementation with better one * add comment --- libs/base/core.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/libs/base/core.cpp b/libs/base/core.cpp index 3bde2225f..80c06c186 100644 --- a/libs/base/core.cpp +++ b/libs/base/core.cpp @@ -1338,8 +1338,27 @@ namespace Math_ { //% TNumber pow(TNumber x, TNumber y) { #ifdef PXT_POWI - // regular pow() from math.h is 4k of code - return fromDouble(__builtin_powi(toDouble(x), toInt(y))); + // regular pow() from math.h is 4k of code, but it can + // also be expressed as exp(y * log(x)) which is less + // performant than pow() but doesn't increase code size + double dx = toDouble(x); + double dy = toDouble(y); + + // shortcut to integer pow if y is an integer + if (::floor(dy) == dy) { + return fromDouble(__builtin_powi(dx, dy)); + } + if (dx > 0) { + return fromDouble(::exp(dy * ::log(dx))); + } + if (dx == 0) { + if (dy < 0) { + // positive infinity + return fromDouble(HUGE_VAL); + } + return x; + } + return fromDouble(::log(dx)); #else return fromDouble(::pow(toDouble(x), toDouble(y))); #endif