【问题标题】:Working on code to calculate cosine with factorial sum使用阶乘计算余弦的代码
【发布时间】:2018-10-06 13:22:42
【问题描述】:

我一直在为这段代码苦苦挣扎,只是似乎没有理解我做错了什么。

代码假设计算:一系列“余弦”的总和,模式为 [(-1)^i(x)^2i]/(2i)!

到目前为止,这是我的代码:

#include <stdio.h>
#include <math.h>

float factorial(int n){
    if (n==0)
        return 1;
    else
        return 2*n*factorial(n-1);
}

int main (){
    float i, n;
    float sum=0;
    printf("Enter desired interger: ");
    scanf("%f", &n);

    for (i=0; i<=1; i++) 
        sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(n));

    printf("The value is %f\n", sum);
    return 0;
}

我仍在努力,任何信息或帮助将不胜感激!

编辑:

刚刚解决了,伙计们,这是我必须为我的教授使用的新格式:

#include <stdio.h>
#include <math.h>
int factorial(int n)
{
if (n==0) return 1;
else
return n*factorial(n-1);
}
float mycos(float x)
{
float sum=0;
int i;
for (i=0;i<=10;i++) sum = sum + (pow(-1,i)*pow(x,2*i))/factorial(2*i);
return sum;
}
int main()
{
int i=1;
printf("     x    mycos(x)   cos(x)\n");
for (i=1;i<=10;i++)
printf(" %f %f %f\n", i*.1, mycos(i*.1), cos(i*.1));
return 0;
}

谢谢大家的解释,他们帮了大忙!

【问题讨论】:

  • 所以这是余弦的泰勒展开级数!什么 IS 或 ISNT 对您有用?
  • 我认为我最大的问题是理解问题以及如何成功翻译成计算机可以理解的格式。到最后我才意识到我必须将其分解以使其正常工作。
  • 您还应该在我的回答下查看 Ed Heal 的评论,因为他谈到了进一步的改进,通过保持运行分母阶乘来更好地执行!我不知道确切的任务是什么,但是........

标签: c


【解决方案1】:

我看到的一件事是,您在 main 中的 for 循环仅运行 2 次真正的迭代,一次用于 i == 0,另一次用于 i == 1。

要使泰勒展开式相当有效地工作,它需要运行更多的序列项(更多的循环迭代)。

我看到的另一件事是,你的分母是 n!而不是 (2 * n)!

为了提高效率,我还可以按如下方式实现阶乘例程:

unsigned int factorial(int n){
    unsigned int product = 1;

    for(int I = 1; I <= n; I++) product *= I;

    return product;
}

上面的阶乘例程用于更精确的阶乘计算,也许您不需要它。出于您的目的,浮点变体可能就足够了。

float factorial(int n){
    float product = 1;

    for(int I = 1; I <= n; I++) product *= (float)I;

    return product;
}

我还应该注意为什么我要以这种方式执行阶乘。一般来说,循环构造将比其递归对应物更有效。您当前的实现是递归的,因此我提供的实现应该在性能和内存利用率方面更加高效。

【讨论】:

  • 你修改的阶乘代码的一个问题是它使用整数计算而不是float,你不能存储超过12个!或在int附近。
  • @JonathanLeffler 实际上这不是一个真正的问题,因为阶乘是一个仅整数的数学函数。任何大于 12 的阶乘中的浮点数!只是垃圾(数学上)。但是,在这种特殊情况下,我明白您的观点,浮点估计可能足以计算余弦。我会更新我的答案!
  • 更具体地说,问题在于大于 12 的值的“整数近似阶乘”是(数学上)垃圾,因为数学值太大而无法放入 32 位整数。您通过使用unsigned int 避免了未定义的行为,但这会让您对阶乘的值进行模 2^32 运算。
  • @JonathanLeffler - Toshay :-)
  • 我不明白为什么要为系列中的每个项目计算阶乘。似乎比较浪费。当可以轻松克服时也会溢出。
【解决方案2】:

考虑到计算开销,您需要在某个点停止计算序列。你走得越多,结果就越精确,但你的程序花费的时间越多。这个简单的程序怎么样:

#include <stdio.h>
#include <math.h>

#define ITERATIONS 10 //control how far you go

float factorial(int n){
    if (n==0)
        return 1;
    else
        return n*factorial(n-1);
}

int main (){
    float n;
    float sum=0;
    printf("Enter desired float: ");
    scanf("%f", &n);

    int c, i;
    for (i=0; i<=ITERATIONS; i++) {
        c = (i%2)==0? 1 : -1;
        sum = sum + (c*pow(n,2*i+1))/(factorial(2*i+1));
    }

    printf("The value is %f\n", sum);
    return 0;
}

【讨论】:

  • 这是对我帮助最大的一个,谢谢!
  • 我用了两个答案来弄清楚,你的帮助我看到了输入错误,而另一个更多地谈论了概念并帮助我意识到我的思维过程是错误的。我只能选择一个,但我仍然对你的回复投了赞成票。 (我希望我实际上可以勾选两者)。如果我冒犯了你,我很抱歉,但感谢你看到我的帮助请求。
  • 别担心,我的朋友;)我也喜欢另一个答案。祝您在 C 编码方面取得成功。
【解决方案3】:

1.) 你只是在阶乘函数return 2*n*factorial(n-1); 中乘以偶数,只会给出偶数。相反,您可以在此处将 n 替换为 2n - sum = sum + (pow(-1,i)*pow(n,2*i))/(factorial(2n)); 这将给出正确的 (2n!)。 2.) 检查迭代次数for (i=0; i&lt;=1; i++) 这只会运行你的循环两次。尝试更多没有。迭代次数以获得更准确的答案。

【讨论】:

    【解决方案4】:

    您为什么要为系列中的每个项目计算功率等?还需要将数字保持在适合数据类型的范围内

    即为cos

    bool neg_sign = false;
    float total = 1.0f;
    float current = 1.0f;
    for (int i = 0; i < length_of_series; ++i) {
        neg_sign = !neg_sign;
        current = current * (x / ((2 * i) + 1)) * (x / (( 2 * i) + 2));
        total += neg_sign ? -current : current;
    }
    

    编辑

    请看http://codepad.org/swDIh8P5

    【讨论】:

    • sign = !sign,你的意思是neg_sign 吗?
    • @Mhd.Tahawi - 是的 - 只是在解决这个问题
    • 这是作业的一部分,我需要在我自己的余弦函数和 math.h 库的余弦函数中显示“x”的值并比较结果。目标是弄清楚如何编写和创建能够绘图的必要数据。你做的比我现在的掌握水平要高,但我希望能尽快理解(我的经验包括大约4-6周,我被这门课扔进了火中哈哈哈)。感谢您的意见!
    • @Edward - 我只是对原始求和应用了一些代数。如何从 (n-2) 阶乘中生成第 n 个阶乘?你如何从 x^(n-2) 得到 x^n?当然,你可以算出来 - 一点数学。然后只需进行一些重新排列以保持相似幅度的乘法以减少错误
    【解决方案5】:
    #include<stdio.h>
    # define PRECISION 10                      /*the number of terms to be processed*/
    main()
    {
                     float x,term=1,s=1.0;
                     int i,a=2;
                     scanf("%f",&x);
                     x=x*x;
                     for(i=1;i<PRECISION;i++)
                     {
                               term=-term*x/(a*(a-1));
                               s+=term;
                               a+=2;
                     }
                     printf("result=%f",s);
    }
    

    【讨论】:

      【解决方案6】:

      您的 factorial() 函数实际上计算了 2n.n!,这可能不是您的想法。要计算(2n)!,你需要从函数体中移除2*并调用factorial(2*n)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 1970-01-01
        • 2016-06-16
        • 2018-03-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多