以计算 sinθ 和 cosθ 为例:
步骤1:角度预处理
将输入角度 θ 归约到 [−π/2,π/2] 范围内(利用三角函数的周期性)。
步骤2:初始化
- 初始向量:x0=1/K, y0**=0**(校正因子提前补偿)
- 剩余角度:z0=θ
步骤3:迭代旋转
// 预计算arctan(2^-i)的值(单位:弧度)
const float angle_table[] = {
0.7853981634f, // arctan(1) = 45°
0.4636476090f, // arctan(1/2) ≈ 26.565°
0.2449786631f, // arctan(1/4) ≈ 14.036°
0.1243549945f, // arctan(1/8) ≈ 7.125°
0.0624188100f, // arctan(1/16) ≈ 3.576°
0.0312398334f, // arctan(1/32) ≈ 1.790°
0.0156237286f, // arctan(1/64) ≈ 0.895°
0.0078123411f, // arctan(1/128) ≈ 0.448°
0.0039062301f, // arctan(1/256) ≈ 0.224°
0.0019531225f // arctan(1/512) ≈ 0.112°
};
#define ITERATIONS 10 // 迭代次数(精度由迭代次数决定)
void cordic(float theta, float *sin_out, float *cos_out) {
// 初始化
float x = 1.0f / 0.607252935f; // 1/K,K≈0.60725
float y = 0.0f;
float z = theta; // 剩余角度
// 迭代旋转
for (int i = 0; i < ITERATIONS; i++) {
float x_new, y_new;
if (z >= 0) { // 正向旋转
x_new = x - y * (1.0f / (1 << i));
y_new = y + x * (1.0f / (1 << i));
z -= angle_table[i];
} else { // 反向旋转
x_new = x + y * (1.0f / (1 << i));
y_new = y - x * (1.0f / (1 << i));
z += angle_table[i];
}
x = x_new;
y = y_new;
}
*cos_out = x;
*sin_out = y;
}
代码示例与测试
测试代码
#include <stdio.h>
#include <math.h>
int main() {
float theta = 0.5235988f; // 30°的弧度值 π/6 ≈ 0.5235988
float sin_theta, cos_theta;
cordic(theta, &sin_theta, &cos_theta);
printf("CORDIC结果:\n");
printf("sin(30°) = %.6f (误差: %.6f)\n", sin_theta, fabs(sin_theta - 0.5f));
printf("cos(30°) = %.6f (误差: %.6f)\n", cos_theta, fabs(cos_theta - sqrt(3)/2));
printf("\n标准库结果:\n");
printf("sin(30°) = %.6f\n", sin(theta));
printf("cos(30°) = %.6f\n", cos(theta));
return 0;
}
|