From 0f709b27617ec27ed46c3a5869d6ed746275a385 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 26 Aug 2024 09:38:58 -0700 Subject: [PATCH] replace pxt_powi implementation with better one --- libs/base/core.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/libs/base/core.cpp b/libs/base/core.cpp index 3bde2225f..9c2789f2c 100644 --- a/libs/base/core.cpp +++ b/libs/base/core.cpp @@ -1338,8 +1338,26 @@ 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) { + return fromDouble(HUGE_VAL); + } + return x; + } + return fromDouble(::log(dx)); #else return fromDouble(::pow(toDouble(x), toDouble(y))); #endif