From d75b6ad8892f71f4ea69dfda865cc11e5afa7834 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Mon, 1 Jul 2019 18:31:54 +0200 Subject: [PATCH] Moved FastPrecisePow and TaylorLog to sonoff_float.ino for consistency --- sonoff/support.ino | 60 --------------------------------------- sonoff/support_float.ino | 61 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 60 deletions(-) diff --git a/sonoff/support.ino b/sonoff/support.ino index ba0a7bbad..41e5ffd3b 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -650,66 +650,6 @@ void ResetGlobalValues(void) } } -double FastPrecisePow(double a, double b) -{ - // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ - // calculate approximation with fraction of the exponent - int e = abs((int)b); - union { - double d; - int x[2]; - } u = { a }; - u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); - u.x[0] = 0; - // exponentiation by squaring with the exponent's integer part - // double r = u.d makes everything much slower, not sure why - double r = 1.0; - while (e) { - if (e & 1) { - r *= a; - } - a *= a; - e >>= 1; - } - return r * u.d; -} - -float FastPrecisePowf(const float x, const float y) -{ -// return (float)(pow((double)x, (double)y)); - return (float)FastPrecisePow(x, y); -} - -double TaylorLog(double x) -{ - // https://stackoverflow.com/questions/46879166/finding-the-natural-logarithm-of-a-number-using-taylor-series-in-c - - if (x <= 0.0) { return NAN; } - double z = (x + 1) / (x - 1); // We start from power -1, to make sure we get the right power in each iteration; - double step = ((x - 1) * (x - 1)) / ((x + 1) * (x + 1)); // Store step to not have to calculate it each time - double totalValue = 0; - double powe = 1; - double y; - for (uint32_t count = 0; count < 10; count++) { // Experimental number of 10 iterations - z *= step; - y = (1 / powe) * z; - totalValue = totalValue + y; - powe = powe + 2; - } - totalValue *= 2; -/* - char logxs[33]; - dtostrfd(x, 8, logxs); - double log1 = log(x); - char log1s[33]; - dtostrfd(log1, 8, log1s); - char log2s[33]; - dtostrfd(totalValue, 8, log2s); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("input %s, log %s, taylor %s"), logxs, log1s, log2s); -*/ - return totalValue; -} - uint32_t SqrtInt(uint32_t num) { if (num <= 1) { diff --git a/sonoff/support_float.ino b/sonoff/support_float.ino index e7b7e62d6..fc2dccf04 100644 --- a/sonoff/support_float.ino +++ b/sonoff/support_float.ino @@ -17,6 +17,66 @@ along with this program. If not, see . */ +double FastPrecisePow(double a, double b) +{ + // https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/ + // calculate approximation with fraction of the exponent + int e = abs((int)b); + union { + double d; + int x[2]; + } u = { a }; + u.x[1] = (int)((b - e) * (u.x[1] - 1072632447) + 1072632447); + u.x[0] = 0; + // exponentiation by squaring with the exponent's integer part + // double r = u.d makes everything much slower, not sure why + double r = 1.0; + while (e) { + if (e & 1) { + r *= a; + } + a *= a; + e >>= 1; + } + return r * u.d; +} + +float FastPrecisePowf(const float x, const float y) +{ +// return (float)(pow((double)x, (double)y)); + return (float)FastPrecisePow(x, y); +} + +double TaylorLog(double x) +{ + // https://stackoverflow.com/questions/46879166/finding-the-natural-logarithm-of-a-number-using-taylor-series-in-c + + if (x <= 0.0) { return NAN; } + double z = (x + 1) / (x - 1); // We start from power -1, to make sure we get the right power in each iteration; + double step = ((x - 1) * (x - 1)) / ((x + 1) * (x + 1)); // Store step to not have to calculate it each time + double totalValue = 0; + double powe = 1; + double y; + for (uint32_t count = 0; count < 10; count++) { // Experimental number of 10 iterations + z *= step; + y = (1 / powe) * z; + totalValue = totalValue + y; + powe = powe + 2; + } + totalValue *= 2; +/* + char logxs[33]; + dtostrfd(x, 8, logxs); + double log1 = log(x); + char log1s[33]; + dtostrfd(log1, 8, log1s); + char log2s[33]; + dtostrfd(totalValue, 8, log2s); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("input %s, log %s, taylor %s"), logxs, log1s, log2s); +*/ + return totalValue; +} + // All code adapted from: http://www.ganssle.com/approx.htm /// ======================================== @@ -32,6 +92,7 @@ inline float atanf(float x) { return atan_66(x); } inline float asinf(float x) { return asinf1(x); } inline float acosf(float x) { return acosf1(x); } inline float sqrtf(float x) { return sqrt1(x); } +inline float powf(float x, float y) { return FastPrecisePow(x, y); } // Math constants we'll use double const f_pi=3.1415926535897932384626433; // f_pi