1

I can't seem to find the error. I need a fresh pair of eyes. I am trying to calculate the values of Cos/Sin/Tan of an angle in C++ without using built-in functions or libraries. These are the only requirements.

This is what I have gotten so far: I have written a function to calculate the exponential values, factorials and the required values.

I keep getting errors and I don't know where they originate from. Some numbers give me exactly the right answers and others are so far off. So could you tell me what I am doing wrong here?

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

double bernoulli_numbers[] = { 1, -1/2.0, 1/6.0, -1/30.0, 5/66.0, -691/2730.0, 7/6.0, -3617/510.0, 43867/798.0, -174611/330.0, 854513/138.0};

int angleToRadian(int angle) {
    float rad_angle;
    rad_angle = angle * (M_PI / 180);
    return rad_angle;
}

int calculatingExponents(int num, int power) {
    long double result = 1;
    for (int i = 0; i < power ; ++i) {
        result *= num;
    }
    return result;
}

unsigned long long calculatingFactorials(int n) {
    unsigned long long factorial = 1;
    if ( n < 0 ) {
        cout << "Can't compute factorials for negative numbers" << endl;
    }
    else if ( n < 2 ) {
        return 1;
    }
    else {
        for (int i = n; (i >= 2) ; i--) {
            factorial = factorial * i;
        }
    }
    return factorial;
}

void calculatingCos(double angle) {
    long double numerator;
    long double last_term;
    unsigned long long denominator;
    long double result;
    long double final_result = 0;
    for (int i = 0; i < 15; ++i) {
        numerator   = calculatingExponents(-1, i);
        denominator = calculatingFactorials(2 * i);
        last_term   = calculatingExponents(angle, (2 * i));
        result =  (numerator / denominator) * last_term;
        final_result += result;
    }
    cout << "The Cosine of the angle = " << final_result << endl;
}

void calculatingSin(double angle) {
    long double numerator;
    long double last_term;
    unsigned long long denominator;
    long double result;
    long double final_result = 0;
    for (int i = 0; i < 15; ++i) {
        numerator   = calculatingExponents(-1, i);
        denominator = calculatingFactorials((2 * i) + 1);
        last_term   = calculatingExponents(angle, ((2 * i) + 1));
        result =  (numerator / denominator) * last_term;
        final_result += result;
    }
    cout << "The Sine of the angle = " << final_result << endl;
}

void calculatingTan(double angle) {
    int bernoulli_index;
    long double bernoulli_number;
    long double numerator;
    long double last_term;
    unsigned long long denominator;
    long double result;
    long double final_result = 0;
    for (int i = 0; i < 15; ++i) {
        bernoulli_index = (2 * i) + 2;
        bernoulli_number = bernoulli_numbers[bernoulli_index];
        numerator   =
        calculatingExponents(-1, i)
        *
        calculatingExponents(2, (2 * i) + 2)
        *
        ( calculatingExponents(2, (((2 * i) + 2) * 1)) - 1) * bernoulli_number;
        denominator = calculatingFactorials((2 * i) + 2);
        last_term   = calculatingExponents(angle, (2 * i) + 1);
        result =  (numerator / denominator) * last_term;
        final_result += result;
    }
    cout << "The Tan of the angle = " << final_result << endl;
}

int main() {
    int degree_angle;
    int x;
    cout << "Please input an angle in degrees:" << endl;
    cin >> degree_angle;
    x = angleToRadian(degree_angle);
    
    calculatingCos(x);
    calculatingSin(x);
    calculatingTan(x);
}

Some the errors I am getting are:

Input: 180
Output: 
The Cosine of the angle = -0.989992
The Sine of the angle = 0.14112
The Tan of the angle = 3.49908e+07
Expected Outputs:
The Cosine of the angle = -1
The Sine of the angle = 0
The Tan of the angle = 0

Input: 60
Output:
The Cosine of the angle = 0.540302
The Sine of the angle = 0.841471
The Tan of the angle = 1705.3
Expected Outputs:
The Cosine of the angle = 0.5
The Sine of the angle = 0.86602540378
The Tan of the angle = 1.73205080757

1 Answers1

1

A lot of parameters and variables are int when they only make sense as doubles.

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

double bernoulli_numbers[] = { 1, -1/2, 1/6, -1/30, 5/66, -691/2730, 7/6, -3617/510, 43867/798, -174611/330, 854513/138};

double angleToRadian(int angle) {
    double rad_angle = angle * (M_PI / 180);
    return rad_angle;
}

angleToRadian previously returned an int, there are pi radians in a circle so angles under 360 degrees are going to snap to 0, 1, 2 or 3 radians. You need to return a decimal to get a correct conversion.

long double calculatingExponents(double num, int power) {
    long double result = 1;
    for (int i = 0; i < power ; ++i) {
        result *= num;
    }
    return result;
}

The num parameter in calculatingExponents takes the decimal angle as a result of angleToRadians, so num, result and the return type of calculatingExponents all need to be floating point numbers too.

unsigned long long calculatingFactorials(int n) {
    unsigned long long factorial = 1;
    if ( n < 0 ) {
        cout << "Can't compute factorials for negative numbers" << endl;
    }
    else if ( n < 2 ) {
        return 1;
    }
    else {
        for (int i = n; (i >= 2) ; i--) {
            factorial = factorial * i;
        }
    }
    return factorial;
}

If you're using an unsigned long long but returning an int, you're relying on implementation defined behaviour, so have no guarantees of a reasonable answer.

int main() {
    int degree_angle = 45;
    cout << "Angle in degrees: " << degree_angle << endl;
    double x = angleToRadian(degree_angle);
    
    calculatingCos(x);
    calculatingSin(x);
    calculatingTan(x);
}

Again angleToRadian returns a floating point number, so x needs to be a floating point type.

These modifications seems to correct sine and cosine between -90 and 90 degrees.

I'm not yet sure what mistake is happening in the tangent calculation.

user213305
  • 402
  • 2
  • 10
  • Thank you so much! That resolved most of the errors and your explanation is great! Now I understand a lot more about how I should define functions in C++! – Mahmoud Daker May 24 '21 at 11:01
  • I'm pretty sure the tan error is related to your ordering of bernoulli numbers, you only want the even ones, but you've listed the 0th, 1st, 2nd, 4th, 6th, going up in 2s, so you index is going to be wrong. – user213305 May 24 '21 at 11:03
  • The formula for Tan(x) using Bernoulli expansion calculates Bernoulli numbers using B₂ₙ₊₂ – Mahmoud Daker May 24 '21 at 11:10
  • 1
    Fiddled around with the tan and Bernoulli numbers too: https://godbolt.org/z/ej1zME3EE – user213305 May 24 '21 at 11:48