2025-03-05 学习记录--C/C++-PTA 习题5-7 使用函数求余弦函数的近似值
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻
一、题目描述 ⭐️
二、代码(C语言)⭐️
1.0
版本 ❌
// 计算阶乘的函数
int getMultiply(int n) {
int result = 1; // 初始化结果为 1
for (int i = 1; i <= n; i++) {
result *= i; // 累乘计算阶乘
}
return result; // 返回阶乘结果
}
// 计算泰勒级数中每一项的函数
double getItem(double x, int i) {
// 返回当前项的值:x^i / i!
return pow(x, i) / getMultiply(i);
}
// 计算余弦函数的泰勒级数展开
double funcos(double e, double x) {
int i = 0; // 当前项的指数,初始为 0
int count = 0; // 计数器,用于判断当前项是否需要加负号
double item = 1; // 当前项的值,初始为第一项 1(x^0 / 0! = 1)
double result = 1; // 最终结果,初始为第一项 1
// 循环计算每一项,直到当前项的绝对值小于精度 e
while (fabs(item) >= e) {
count++; // 计数器加 1
i += 2; // 指数增加 2,因为余弦级数的项是偶数幂
item = getItem(x, i); // 计算当前项的值
if (count % 2 != 0) {
item *= (-1); // 如果计数器是奇数,当前项取负
}
result += item; // 将当前项累加到结果中
}
return result; // 返回最终结果
}
2.0
版本 ✅
1.0
版本的代码通过计算阶乘来实现泰勒级数展开,但当x
较大或e
较小时,阶乘会迅速增长,导致数值溢出或精度丢失。为了避免这些问题,我们需要优化代码,避免直接计算阶乘。
优化思路: 👇🏻
- 避免直接计算阶乘:使用递推公式计算每一项的值,而不是每次都重新计算阶乘。
- 减少重复计算:每次计算新项时,利用前一项的结果,避免重复计算。
double funcos(double e, double x) {
double result = 1.0; // 最终结果,初始为第一项 1
double item = 1.0; // 当前项的值,初始为第一项 1
int n = 2; // 从第二项开始计算
int sign = -1; // 符号,初始为负
// 循环计算每一项,直到当前项的绝对值小于精度 e
while (fabs(item) >= e) {
// 递推公式计算新项:item = item * (x^2) / (n * (n-1))
item *= (x * x) / ((n - 1) * n);
result += sign * item; // 根据符号累加到结果中
sign *= -1; // 符号取反
n += 2; // 更新 n,每次增加 2
}
return result;
}
【注意 📢 】在
C
语言中,double
类型的初始值后加小数点(如1.0
)是为了明确表示这是一个浮点数常量,而不是整数常量。
- 浮点数与整数的区别:
- 整数常量:例如
1
,默认是int
类型。- 浮点数常量:例如
1.0
,默认是double
类型。- 在
C
语言中,1
和1.0
是不同的:
1
是整数常量,类型为int
。1.0
是浮点数常量,类型为double
。