Алгоритм вычисления косинуса - PullRequest
0 голосов
/ 19 января 2012

Я создал эту функцию CalculateCos:

int Factorial (long int n)
{
    long int r = 1;
    for (int i = 2; i<=n; i++)
    {
        r = r*i;    
    }   

    return r;
}

float CalculateVariable(int CVnumber, int CVloopCounter)
{
    float CVresult = 0;
    CVresult = pow(CVnumber, (CVloopCounter*2)) / (long int)Factorial(CVnumber*2);

    return CVresult;
}

float CalculateCos(int number)
{
    float result = 1;
    int loopCounter = 1;
    int minusOrPlus = 1;
    while(loopCounter <= precision && loopCounter <= 8)
    {
        if(!minusOrPlus)
        {
            result = result - CalculateVariable(number, loopCounter);
            printf("%f\n", result);
            minusOrPlus = 1;
        }
        else
        {
            result = result + CalculateVariable(number, loopCounter);
            printf("%f\n", result);
            minusOrPlus = 0;
        }
        loopCounter++;
      }
      return result;
}

Причина, по которой я печатаю f после вычитания или сложения, заключается в том, что он дает мне странный вывод, например:

Enter a number, for the cos function
6
1.000000
0.999997
1.000095
0.996588
1.122822
-3.421593
160.177368
-5729.385254
Result is: -5729.3852539
Official function result is:  0.9601703

Можете ли вы помочь мне получить правильные результаты по этому вопросу?

UPDATE:

Теперь мое решение:

float CalculateCos(float number)
{
    float result = 0;
    float step = 1;
    int loopCounter = 1;

    while(loopCounter <= 5)
    {
        step = step * (-number) * number / (((2*loopCounter)-1)*((2*loopCounter)-2));
        result += step;
        loopCounter++;
    }

    return result;
}

1 Ответ

6 голосов
/ 19 января 2012

Текущая проблема:

, поскольку ваша функция Factorial возвращает int, и вы преобразуете ее в long int, ее результат будет переполнен даже до того, как ввод перейдет к 16 в вашем случае (14!> Max_int).

Вы рассчитываете cos, используя ряды Тейлора:

cos (x) = 1 - x 2 / 2!+ х 4 / 4!- х 6 / 6!+ ...

Я не собираюсь писать код.Но в вашей программе есть некоторые ошибки, которые можно легко исправить:

  1. Ввод в радианах, поэтому number должно быть float.
  2. Расчет каждогоШаг ряда Тейлора с использованием возведения в степень и факториала по отдельности приводит к переполнению очень скоро.Правильный способ - поддерживать переменную float: сначала step = 1 и в итерации цикла k th step = step * (- x) * x / ((2*k-1)*(2*k)).Таким образом, вы просто добавляете step к result в цикле и больше не нуждаетесь в minusOrPlus.
  3. Количество итераций цикла ограничено 8, что слишком мало, поэтомурезультат может быть недостаточно точным.
  4. Я не вижу, чтобы вы использовали переменную precision.Это может быть использовано для проверки точности результата.Например, когда abs(step) < precision, мы собираемся завершить цикл.
...