Originally Posted by
Hodor
Looking at it again I was mistaken. I didn't notice that the "coefficients" were being added backwards and the implementation is using methods described here:
Horner's method - Wikipedia
I don't know which of the below implementations below I prefer, but I do know that comments should be added (if there was comments in the initial code I'd not have initially thought it was implemented incorrectly, for example )
Code:
#include <stdio.h>
#include <math.h>
double calc_abv(double abw);
double calc_abv2(double abw);
double calc_abv3(double abw);
int main()
{
for (double abw = 0.0; abw <= 1.0; abw += 0.1) {
printf("%lf, %lf, %lf, %lf\n", abw, calc_abv(abw), calc_abv2(abw), calc_abv3(abw));
}
return 0;
}
double calc_abv(double abw)
{
const double a = -0.000039705486746795932;
const double b = 1.2709666849144778;
const double c = -0.40926819348115739;
const double d = 2.0463351302912738;
const double f = -7.8964816507513707;
const double g = 15.009692673927390;
const double h = -15.765836469736477;
const double i = 8.8142267038252680;
const double j = -2.0695760421183493;
double temp = j;
temp = temp * abw +i;
temp = temp * abw +h;
temp = temp * abw +g;
temp = temp * abw +f;
temp = temp * abw +d;
temp = temp * abw +c;
temp = temp * abw +b;
double abv = temp * abw +a;
return abv;
}
double calc_abv2(double abw)
{
const double a = -0.000039705486746795932;
const double b = 1.2709666849144778;
const double c = -0.40926819348115739;
const double d = 2.0463351302912738;
const double f = -7.8964816507513707;
const double g = 15.009692673927390;
const double h = -15.765836469736477;
const double i = 8.8142267038252680;
const double j = -2.0695760421183493;
return a +
b * abw +
c * pow(abw, 2) +
d * pow(abw, 3) +
f * pow(abw, 4) +
g * pow(abw, 5) +
h * pow(abw, 6) +
i * pow(abw, 7) +
j * pow(abw, 8)
;
}
double calc_abv3(double abw)
{
static const double coefficients[] = {
-0.000039705486746795932,
1.2709666849144778,
-0.40926819348115739,
2.0463351302912738,
-7.8964816507513707,
15.009692673927390,
-15.765836469736477,
8.8142267038252680,
-2.0695760421183493
};
double abv = coefficients[0];
double abw_mult = abw;
for (size_t i = 1; i < sizeof(coefficients) / sizeof(coefficients[0]); ++i)
{
abv = abv + coefficients[i] * abw_mult;
abw_mult *= abw;
}
return abv;
}
Edit: or laserlight's implementation, of course