正弦與餘弦函數可通過泰勒級數展開計算:
其中 x 為弧度制。程式中將輸入角度轉換:rad = deg * PI / 180。
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
缺陷:int 型別 13! 即溢位(>2¹⁷),且遞歸開銷大。建議改用迭代並預計算或使用 double 累乘。
原代碼使用 pow(x,i)/factorial(i) > 1e-7 作為迴圈條件,存在效能問題:
x 時項數增多,階乘快速溢位。利用項與前項關係:
// sin: term_k = -term_{k-1} * x² / ((2k)*(2k-1))
// cos: term_k = -term_{k-1} * x² / ((2k-1)*(2k-2))
單次迴圈累加,避免重複計算,複雜度降為 O(n)。
#include <stdio.h>
#include <math.h>
#define PI 3.14159265358979323846
#define EPS 1e-12
double my_sin(double x) {
// 區間縮減:利用週期性將 x 映射到 [-π, π]
x = fmod(x, 2*PI);
if (x < -PI) x += 2*PI;
else if (x > PI) x -= 2*PI;
double term = x, sum = x;
int n = 1;
while (fabs(term) > EPS) {
term *= -x*x / ((2*n)*(2*n+1));
sum += term;
n++;
}
return sum;
}
double my_cos(double x) {
x = fmod(x, 2*PI);
if (x < -PI) x += 2*PI;
else if (x > PI) x -= 2*PI;
double term = 1.0, sum = 1.0;
int n = 1;
while (fabs(term) > EPS) {
term *= -x*x / ((2*n-1)*(2*n));
sum += term;
n++;
}
return sum;
}
int main() {
double deg;
printf("Enter angle in degrees: ");
if (scanf("%lf", °) != 1) return 1;
double rad = deg * PI / 180.0;
printf("sin(%.2f°) = %.10f (lib: %.10f)\n", deg, my_sin(rad), sin(rad));
printf("cos(%.2f°) = %.10f (lib: %.10f)\n", deg, my_cos(rad), cos(rad));
return 0;
}
fabs(term) > EPS 判斷項值貢獻,而非固定項數。sin/cos 對比,確保正確性。atan2 實現完整三角函數庫(tan, asin, acos 等)。