Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用c语言创建Sin公式_C_Visual C++_Trigonometry - Fatal编程技术网

用c语言创建Sin公式

用c语言创建Sin公式,c,visual-c++,trigonometry,C,Visual C++,Trigonometry,大家好,我正在尝试实现一个类似fomular sin的程序 程序将编译,但在运行时,我没有从输入中获得正确的值。我仍然得到一个负值。 有人能帮我吗?我看了一下其他帖子,但这对我没有帮助:(。 我的代码是: #include <stdio.h> #include <stdlib.h> int fac (int a) { // fac. => factorial and i is for the loop int i,fac; fac=1;

大家好,我正在尝试实现一个类似fomular sin的程序 程序将编译,但在运行时,我没有从输入中获得正确的值。我仍然得到一个负值。 有人能帮我吗?我看了一下其他帖子,但这对我没有帮助:(。 我的代码是:

#include <stdio.h>
#include <stdlib.h>

int fac (int a) { // fac. => factorial and i is for the loop

    int i,fac;
        fac=1;

    for (i=1; i<=a; i++){
        fac=fac*i;
    }
    return fac;
}
int power_func(int x,int y) // x is exponent and y is the number that would be multiplied by itself.
     {
         int i;//i is for the loop
         int ret = 1;
         for(i=1;i<=x;i++)
         {
             ret *= y;
         }
         return ret;
     }
int main()
{
    int num,denom,i;//num. is numerator and denom. is denominator
    int sin,x,result=0;
    printf("Enter the number of x \n");
    scanf("%d",&x);
    for(i=0;i<x;i++)
    {

    num= power_func(2*i+1,x);
    denom=fac((2*i+1));
    sin=power_func(i,-1)*num/denom;
    result =result+sin;
    printf("%d \n",result);
    }

    return 0;
}
#包括
#包括
intfac(inta){//fac.=>阶乘,i代表循环
int i,fac;
fac=1;

对于(i=1;i您对代码有各种误解。首先,让我们看看您提供的公式:

sin(x) = sum((−1)^k * x^(2*k + 1) / (2*k + 1)!   for x ∈ R;   k = 0, ..., infinity
正弦函数取一个实数并返回一个实数。因此,您应该为x和sin(x)使用浮点类型。使用
双精度
。让我们编写一个模拟
sin
的函数:

当有无限多个术语时,上面的系列是准确的。当然,我们不能计算那么多,这也将是浪费时间,因为这些术语越来越小,直到它们不再由一个
表示。因此,让我们选择一个最大数量的术语,例如

enum {
    nTerms = 8
};
阶乘增长很快。一个普通的32位整数可以容纳12!=479001600。一个64位整数可以容纳20!=2432902008176640000。因为我们将在
double
计算中使用这些阶乘,我们也可以在这里使用
double
。这甚至允许我们精确地表示22!=11240007277607680000

幂函数也应该有一个
double
base。指数是整数。(但请使用更自然的顺序
power(base,exp)

最后,
(−1) ^k
只是一个交替符号。当
k
为偶数或奇数时,它为正

综上所述:

double fact(int n)
{
    double result = 1.0;

    while (n > 0) {
        result *= n;
        n--;
    }

    return result;
}

double power(double a, int n)
{
    double result = 1.0;

    while (n > 0) {
        result *= a;
        n--;
    }

    return result;
}

enum {
    nTerms = 8
};

double my_sin(double x)
{
    double result = 0.0;
    double sign = 1.0;

    for(int k = 0; k < nTerms; k++)
    {
        double num = power(x, 2*k + 1);
        double denom = fact(2*k + 1);
        double term = sign * num / denom;

        result = result + term;
        sign = -sign;
    }

    return result;
}
我们可以看出,我们做得并不差:

           x       my_sin(x)          sin(x)      difference
    --------    ------------    ------------    ------------
           0               0               0               0
         0.1       0.0998334       0.0998334     1.38778e-17
         0.2        0.198669        0.198669     2.77556e-17
         0.3         0.29552         0.29552               0
         0.4        0.389418        0.389418    -5.55112e-17
         0.5        0.479426        0.479426               0
         0.6        0.564642        0.564642               0
         0.7        0.644218        0.644218               0
         0.8        0.717356        0.717356               0
         0.9        0.783327        0.783327    -4.44089e-16
           1        0.841471        0.841471    -2.77556e-15
         1.1        0.891207        0.891207    -1.43219e-14
         1.2        0.932039        0.932039    -6.20615e-14
         1.3        0.963558        0.963558    -2.42029e-13
         1.4         0.98545         0.98545    -8.52318e-13
(但离零越远,情况就越糟。请为
nTerms
尝试其他值)


我在上面的评论中说过,你不需要计算阶乘和幂,这是事实。如果你看一下级数的项,你会发现:

s[n] = -1 * s[n - 1] * x^2 / (2*n * (2*n +1))

s[0] = x
s[1] = x^3 / (1 * 2 * 3)         =                 x * x^2 / (2 * 3)
s[2] = x^5 / (1 * 2 * 3 * 4 * 5) = x^3 / (1 * 2 * 3) * x^2 / (4 * 5)
s[3] = ...
下面是一个实现该功能的函数。它计算项,直到将它们添加到总和中不会改变它,因为它们太小:

double sin_r(double x)
{
    double sum = x;
    double a = x;
    int n;

    for (n = 1; ; n++) {
        double was = sum;

        a = -a * x*x / (2*n) / (2*n + 1);
        sum += a;

        if (was == sum) break;
    }

    return sum;
}

通过先求第一项的和,加法仍然会失去一些精度,但它的好处是它不必计算阶乘和幂。你甚至不需要

你的
power\u func
是不正确的。它计算
y^(2^x)
@lower我已经将这行更改为num=power\u func(x,2*I+1);但我还是得到了一个类似的答案:输入x3的数字(,-1.000000,1092.000000,4347.000000)结果请看我最初对它计算错误的评论。对不起,我错了后面的部分。哦,嗯,没关系@Lovererm更具体地说,
y=y*y
是个问题。。。
s[n] = -1 * s[n - 1] * x^2 / (2*n * (2*n +1))

s[0] = x
s[1] = x^3 / (1 * 2 * 3)         =                 x * x^2 / (2 * 3)
s[2] = x^5 / (1 * 2 * 3 * 4 * 5) = x^3 / (1 * 2 * 3) * x^2 / (4 * 5)
s[3] = ...
double sin_r(double x)
{
    double sum = x;
    double a = x;
    int n;

    for (n = 1; ; n++) {
        double was = sum;

        a = -a * x*x / (2*n) / (2*n + 1);
        sum += a;

        if (was == sum) break;
    }

    return sum;
}