Moved FastPrecisePow and TaylorLog to sonoff_float.ino for consistency

This commit is contained in:
Stephan Hadinger 2019-07-01 18:31:54 +02:00
parent 15e37ef0bb
commit d75b6ad889
2 changed files with 61 additions and 60 deletions

View File

@ -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) uint32_t SqrtInt(uint32_t num)
{ {
if (num <= 1) { if (num <= 1) {

View File

@ -17,6 +17,66 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
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 // 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 asinf(float x) { return asinf1(x); }
inline float acosf(float x) { return acosf1(x); } inline float acosf(float x) { return acosf1(x); }
inline float sqrtf(float x) { return sqrt1(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 // Math constants we'll use
double const f_pi=3.1415926535897932384626433; // f_pi double const f_pi=3.1415926535897932384626433; // f_pi