You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++实现sinx时出现死循环问题求助

问题分析与修复方案

核心问题

你的代码陷入死循环主要有三个原因:

  • 阶乘变量溢出:int fact的取值范围有限(通常最大为2147483647),当2*n+1超过12时,13! = 6227020800已经超出int上限,溢出后fact会变成负数或极小值,导致term无法趋近于0,永远满足不了term==0的终止条件。
  • 错误的终止条件:浮点数double的精度有限,term会趋近于极小值但永远不会等于0,用term==0作为循环终止条件完全不可行。
  • 泰勒展开初始项缺失:sinx的泰勒展开第一项是x(对应n=0时的项:x^1/1!),你的代码从n=1开始计算,直接跳过了第一项,结果会完全错误。

修复后的基础版本代码

#include <iostream>
#include <cmath>
using namespace std;

int main(){
    double x;
    double sinx = 0.0;
    int n = 0;
    int sign = 1;
    cin >> x;

    // 用当前项的绝对值小于精度阈值作为终止条件
    while (true) {
        int exponent = 2 * n + 1;
        // 改用double存储阶乘,避免溢出
        double fact = 1.0;
        for(int i = 1; i <= exponent; i++){
            fact *= i;
        }
        double term = pow(x, exponent) / fact;
        // 设置精度阈值,比如1e-10,足够满足一般计算需求
        if (fabs(term) < 1e-10){
            break;
        }
        sinx += term * sign;
        sign *= -1;
        n++;
    }
    cout << sinx << endl;
    return 0;
}

高效优化版本

避免重复计算阶乘和幂次,大幅提升运行效率:

#include <iostream>
#include <cmath>
using namespace std;

int main(){
    double x;
    cin >> x;
    double sinx = x; // 初始项为x(n=0时的项)
    double term = x;
    double x_squared = x * x;
    int n = 1;
    int sign = -1;

    while (fabs(term) > 1e-10) {
        // 基于上一项推导当前项,避免重复计算阶乘与幂次
        term = term * x_squared / ((2 * n) * (2 * n + 1));
        sinx += term * sign;
        sign *= -1;
        n++;
    }
    cout << sinx << endl;
    return 0;
}

内容的提问来源于stack exchange,提问作者The Coding Kenan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:50:02