#define PARTPERDEGREE 1
double mysinlut[PARTPERDEGREE * 90 + 1];
double mycoslut[PARTPERDEGREE * 90 + 1];
void MySinCosCreate()
{
int i;
double angle, angleinc;
// Each degree also divided into 10 parts
angleinc = (M_PI / 180) / PARTPERDEGREE;
for (i = 0, angle = 0.0; i <= (PARTPERDEGREE * 90 + 1); ++i, angle += angleinc)
{
mysinlut[i] = sin(angle);
}
angleinc = (M_PI / 180) / PARTPERDEGREE;
for (i = 0, angle = 0.0; i <= (PARTPERDEGREE * 90 + 1); ++i, angle += angleinc)
{
mycoslut[i] = cos(angle);
}
}
double MySin(double rad)
{
int ix;
int sign = 1;
double angleinc = (M_PI / 180) / PARTPERDEGREE;
if(rad > (M_PI / 2))
rad = M_PI / 2 - (rad - M_PI / 2);
if(rad < -(M_PI / 2))
rad = -M_PI / 2 - (rad + M_PI / 2);
if(rad < 0)
{
sign = -1;
rad *= -1;
}
ix = (rad * 180) / M_PI * PARTPERDEGREE;
double h = rad - ix*angleinc;
return sign*(mysinlut[ix] + h*mycoslut[ix]);
}
double MyCos(double rad)
{
int ix;
int sign = 1;
double angleinc = (M_PI / 180) / PARTPERDEGREE;
if(rad > M_PI / 2)
{
rad = M_PI / 2 - (rad - M_PI / 2);
sign = -1;
}
else if(rad < -(M_PI / 2))
{
rad = M_PI / 2 + (rad + M_PI / 2);
sign = -1;
}
else if(rad > -M_PI / 2 && rad < M_PI / 2)
{
rad = abs(rad);
sign = 1;
}
ix = (rad * 180) / M_PI * PARTPERDEGREE;
double h = rad - ix*angleinc;
return sign*(mycoslut[ix] - h*mysinlut[ix]);
}
double MyTan(double rad)
{
return MySin(rad) / MyCos(rad);
}
事实证明,使用除法计算
tan
甚至比原始的tan
函数昂贵。没有任何方法可以使用sin / cos查找表值来计算
tan
,而无需进行除法运算,因为除法在我的MCU上很昂贵。像现在针对sin / cos一样,使用tan / sin或tan / cos提取
tan
LUT并提取结果是否更好? 最佳答案
特别是在微控制器中,y / x除法通常可以通过对数和exp表或使用迭代乘法来优化,直到分母1 +-eps = 1 +-x ^(2 ^ n)为零。
y/X = y / (1-x)
= (1+x)y / (1+x)(1-x)
= (1+x)(1+x^2)y / (1-x^2)(1+x^2)
= (1+x)(1+x^2)(1+x^4)y / (1-x^4)(1+x^4)
关于c - 计算具有sin/cos LUT的棕褐色,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13765457/