I have Written a code for sine function but it is not much accurate

I have written a code for PI() and sin() function but it is not much accurate I want to make it more accurate can anybody tell how can I make it more accurate.
Also I dont want to use constant value of pi. I want to find it out using function to the highest accuracy.
Following is the code

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


double factorial (int a);
double power (double b, int power);

double MySin(double c, int Accuracy = 100);

double MyPi(double accuracy = 50);


int main (void){


//Comment Out below code for testing factorial function
    //  int MyNumber;
    //cout << "Enter the number for which you want factorial to find out?\n";
    //cin >> MyNumber;
    //cout << "Factorial of " << MyNumber << " is " << factorial(MyNumber) << endl;
    //
    //
    //getchar();

//Comment out below code for testing power function
    //double MyNumber;
    //int NumPower;
    //cout << "Enter the number" << endl;
    //cin >> MyNumber;
    //cout << "\nEnter the power" << endl;
    //cin >> NumPower;

    //cout << power(MyNumber,NumPower);


//Comment out below code for testing Sine function
    //cout << MySin(30,1000);


//Comment out below code for testing value of pi
    //cout << MyPi(100000) << "End of line";


}


double MyPi(double accuracy){
double result = 0;
for (double index = 1+accuracy*2; index >= 3; index-=2){

    result = 2+power(index,2)/result;
}

return 4/(1+(1/result));

}

double MySin(double c, int Accuracy){
    c=c*MyPi(1000)/180;
    double result = c;
    int Minus = -1;
    for (int index = 3; index < Accuracy; index+=2 ){
        result = result + Minus * power(c,index)/factorial(index);
        Minus*=-1;  
    }
    return result;

}

double power (double b, int power){
    double result = 1;

    while (power>0){
        result *= b;
        power--;
    }
    return result;

}

double factorial (int a){
    double result;

    if(a==1){
        return 1;
    }else{

        result = a * factorial(a-1);

    }
    return result;

}

Dani AI

Generated

A few targeted fixes will both stop the crashes and give much better accuracy.

The immediate bugs: MyPi currently divides by result when result is still zero (divide-by-zero). factorial is recursive with no a == 0 base case and will overflow the call stack or produce huge intermediate values for modest Accuracy. Computing pi inside every MySin call is expensive. These are the reasons increasing the iteration count makes the program fail rather than converge.

Recommended, practical steps (build on 's good suggestion about range reduction and term recurrence):

  • Fix MyPi evaluation so you never divide by zero (evaluate the continued fraction from the bottom up, or pick a different pi algorithm). Compute pi once, store it (static/const) and reuse it.
  • Avoid recursive factorial and repeated power loops. Compute each sine term from the previous term with a recurrence (next_term = previous_term * factor), so you never compute large factorials or pow() repeatedly. Stop when the absolute value of the next term is below an epsilon (for double something like 1e-15 is typical) rather than looping a fixed number of terms.
  • Do argument reduction into the primary interval (map input to a small symmetric interval and use symmetries to pick sign/quadrant). This drastically reduces the number of terms needed.
  • For more digits: long double gives modest extra precision (platform dependent). For true high-precision pi/sin, use a multiprecision library (Boost.Multiprecision, MPFR/GMP) or a fast pi algorithm (Chudnovsky/Gauss–Legendre) instead of a naive series.

Test with small and large angles, check edge cases (0, multiples of pi/2), and use a relative stopping criterion. These changes fix crashes and give stable, fast convergence.

Recommended Answers

All 2 Replies

If I add calculation levels then the calculation steps becomes long and program crashes. Need to know how to do it accurately.

If you want better precision, you have to care about round-off error accumulation and amplification factors. Generally, things like subtracting numbers that are very close, or dividing number of wildly different magnitudes tend to make the round-off errors blow out of proportion. So, you can't really apply the mathematical formula verbatim and expect good precision all the time, you have to modify it to avoid ill-conditioned operations. I think that this sin function should work a bit better:

double MySin(double c /* in radians */, int Accuracy) {
    // you should clamp the c value within the first period around 0:
    static double pi = MyPi(1000);
    while(c > pi) c -= 2 * pi;
    while(c < -pi) c += 2 * pi;

    double result = c;
    int Minus = -1;
    double c_term = c;
    double c_sqr = c * c;
    for (int index = 3; index < Accuracy; index+=2 ) {
        c_term *= c_sqr / (index * (index - 1));
        result += Minus * c_term;
        Minus *= -1;  
    }
    return result;
}

And, of course, using the type double, you should never expect precision beyond 15 significant digits. For any precision higher than that, you will need to use a library for infinite-precision (variable-length) real number representations.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.