Reigo Hein
Reigo Hein

Reputation: 751

Calculating cosine algorithm

I created this function 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;
}

The reason why I printf after the subtraction or adding, is because it gives me strange output, like:

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

Can you help me to get correct results on this?

UPDATE:

Now my solution is:

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;
}

Upvotes: 1

Views: 5768

Answers (1)

pad
pad

Reputation: 41290

Current problem:

since your Factorial function returns int and you casts it to long int, its result is going to overflow even before the input goes to 16 in your case (14! > max_int).

You're calculating cos using Taylor series:

cos(x) = 1 - x2/2! + x4/4! - x6/6! + ...

I'm not going to write code. But there are some things wrong in your program, which can be fixed easily:

  1. The input is in radian, so number should be a float.
  2. Calculating each step of Taylor series using exponentiation and factorial separately leads to overflow very soon. The correct way is maintaining a float variable: step = 1 at first and in kth loop iteration step = step * (- x) * x / ((2*k-1)*(2*k)). In this way, you simply add step to result in the loop and don't need minusOrPlus anymore.
  3. The number of loop iterations is bounded by 8 which is too small, so the result could be not precise enough.
  4. I don't see you use precision variable anywhere. It could be used to check precision of the result. For example, when abs(step) < precision, we're going to terminate the loop.

Upvotes: 7

Related Questions