mirror of https://github.com/arendst/Tasmota.git
Moved FastPrecisePow and TaylorLog to sonoff_float.ino for consistency
This commit is contained in:
parent
15e37ef0bb
commit
d75b6ad889
|
@ -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) {
|
||||
|
|
|
@ -17,6 +17,66 @@
|
|||
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
|
||||
|
||||
/// ========================================
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue