Creating sine function

This is a discussion on Creating sine function within the C Programming forums, part of the General Programming Boards category; Trying to implement a sine function that uses the series: sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    42

    Creating sine function

    Trying to implement a sine function that uses the series:
    sin(x) = x - x^3/3! + x^5/5! - x^7/7! + ...
    , but it only returns 0.0000. I'm obviously doing it wrong. Any suggestions?

    Code:
    double sine(float angle){
            int y;
            double radians;
            radians = angle * (M_PI / 180.0);
            if(radians > 0.0){
                    for(y = 1; !((fabs(pow(radians, y))/fact(y)) - (pow(radians, y+2)/fact(y+2)) < EPSILON); y = y + 2);//empty body
    
    }
            return ((pow(radians, y))/fact(y));
    }

  2. #2
    Registered User
    Join Date
    Apr 2008
    Posts
    90
    Your loop is running until the difference between two consecutive terms in the series is below your EPSILON threshold. Then you return only a single value in the series, namely the one after the above difference applies.

    What you're doing can be done much more efficiently than calling pow() and fact() for each term. Each term is -(x^2/(x*(x-1))) times the previous term, so start a sum at 0 and a term at x, then on each iteration of the loop add the term to the sum and multiply the term by the above to get the next term.

    Each term eventually gets smaller and smaller. When you get to a point that the term is too small for a double, it becomes 0. Then you exit the loop.

  3. #3
    Registered User
    Join Date
    Feb 2011
    Posts
    42
    What would I do with the sum value? would i do something like..

    Code:
    double sine(float angle){
            while(angle > 0.0){
                    angle = angle * -((pow(angle, 2))/(angle * (angle - 1)));
    }
            return y;
    My instructions are to "compute the sine of "angle" using as many terms in the series as required till two successive approximations differ by no more than .00000001 (EPSILON)"..
    if that helps

  4. #4
    Registered User
    Join Date
    Feb 2011
    Posts
    42
    My apologies, I understand a bit more what you're saying now.
    Code:
    double sine(float angle){
            float y;
            double sum = 0.0;
            y = angle;
            while(y > 0.0){
                    sum = sum + y;
                    y = y * -((pow(y, 2))/(y * (y - 1)));
    }
    return sum;
    }
    However, when passing 45, 36, and .345 as parameters, only .345 returns a value close to what it should be...

    This is some of my output:

    The calculated sine of a 45 degree angle is : 3.659793
    The sine of a 45 degree angle should be: .707106....
    The calculated sine of a 36 degree angle is : 1.690476
    The sine of a 36 degree angle should be: .587785....
    The calculated of a .345 degree angle is : 0.006058
    The sine of a .345 degree angle should be: .00602....

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    90
    You don't want to change angle. Create another variable for the sum and another for the current term. You can also keep track of the previous term and check the difference on each iteration. Also, no need to call pow just to square a number. Just do "angle*angle" instead.

    It turns out I was a little off on the term to multiply. What you actually want is -(angle^2/(y*(y-1))), where y starts at 1 and increases by 2 on each iteration of the loop. That gets you the factorial part.

  6. #6
    Registered User
    Join Date
    Feb 2011
    Posts
    42
    Thank you for your help. I'm trying to follow along as best I can. How do these changes look?
    Code:
    double sine(float angle){
            float y;
            double sum = 0.0;
            
            for(y=1; y>EPSILON; y= y+2){
                    y = y * -((angle*angle)/(y * (y - 1)));
                    sum = sum + y;
    }
    return sum;
    
    }
    I'm not entirely sure if this is what you meant, however I do know that based on this setup here, because y is initialized as 1, the (y*(y-1)) will place 0 in the denominator.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    90
    You need to keep y separate from term. y should only get modified in the "for" statement. terms should be initialized to angle. Also, given that y starts at 1, you're better of using (y+1)*(y+2) for the denominator, and you should first add to the sum before updating the term.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Creating an scanf function inside an function
    By anserudd in forum C Programming
    Replies: 4
    Last Post: 03-25-2011, 09:19 AM
  2. values of sine
    By jacek in forum C Programming
    Replies: 2
    Last Post: 10-31-2009, 04:17 PM
  3. UDF to calculate sine
    By n3cr0_l0rd in forum C Programming
    Replies: 5
    Last Post: 02-26-2009, 07:02 AM
  4. How to program in the inverse sine function
    By Finchie_88 in forum C++ Programming
    Replies: 4
    Last Post: 03-13-2005, 10:56 PM
  5. A faster way to calculate sine function?
    By IcyDeath in forum C++ Programming
    Replies: 6
    Last Post: 11-06-2004, 12:17 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21