#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2006
    Posts
    24
    Rep Power
    0

    A program to calculate sine(x) (C)


    Hello everyone, I am trying to calculate the sine of a number using taylor series.....and sth is wrong with this program.
    It has an inf loop.
    I think it has to do with the float or sth...
    I calculate the terms, until the previous term is equal to the current term...and it dont gets out of the loop....
    Any ideas ?? Thx in Advance.

    Code:
    /****************************************************************************
     *           																*
     *	Sine(x)= x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) .......				*
     *  																		*
     *  																		*
     *																			*
     ****************************************************************************/
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    float fact( float num);
    
    main() {
    	float number,total,new_total;
    	float result,top,bottom;
    	float sign=1.0,exp=1.0;
    	
    	printf("Give a number: ");
    	scanf("%f",&number);
    	result=number;
    	total=number;
    	
    	for (;;) {
    		sign=-sign;
    		exp+=2.0;
    		top=sign*pow(number,exp);
    		bottom=fact(exp);
    		new_total=top/bottom;
    		if (new_total==total)
    			break;
    		total=new_total;
    		result+=total;
    	}
    	
    	printf("Sine of %f=%f\n",number,result);
    	
    }
    
    float fact( float num) {
    	if (num<=1.0)
    		return(1.0);
    	else
    		return(num * fact(num-1.0) );
    }
  2. #2
  3. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2006
    Posts
    102
    Rep Power
    8
    I think you're right about it being float.
    I'm not too up on C++ (just learning at the monment) but I'm guessing that float isn't big enough to hold the Taylor expansion.
    If you change it to double it appears to work fine
    c++ Code:
     
    /****************************************************************************
     *           																*
     *	Sine(x)= x - (x^3)/(3!) + (x^5)/(5!) - (x^7)/(7!) .......				*
     *  																		*
     *  																		*
     *																			*
     ****************************************************************************/
    #include <stdio.h>
    #include <cstdlib>
    #include <math.h>
    #include <iostream>
     
    using namespace std;
     
    double fact( double num);
     
    main() {
    	double number,total,new_total;
    	double result,top,bottom;
    	double sign=1.0,exp=1.0;
     
    	printf("Give a number: ");
    //	scanf("%f",&number);
    	cin>>number;
    	result=number;
    	total=number;
     
    	for (;;) {
    		sign=-sign;
    		exp+=2.0;
    		top=sign*pow(number,exp);
    		bottom=fact(exp);
    		new_total=top/bottom;
    		if (new_total==total)
    			break;
    		total=new_total;
    		result+=total;
    	}
     
    	printf("Sine of %f=%f\n",number,result);
     
    }
     
    double fact( double num) {
    	if (num<=1.0)
    		return(1.0);
    	else
    		return(num * fact(num-1.0) );
    }


    I've added line 11, 12, 14 and 25.
    I used cin as I'm not sure how to make scanf read in a double type (I said I was a noob 2 this :))
    Not fully tested it, but it seems to work


    EDIT: DOESN'T WORK :o
    Last edited by geo_101; February 13th, 2007 at 06:57 AM.
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    You can't compare floats for equality.
    http://en.wikipedia.org/wiki/Floating_point
    In particular, read the link to David Goldberg's paper at the end.

    > if (new_total==total)
    Needs to be something like
    if ( fabs(new_total-total) < 0.0001 )
    You're dealing with approximate numbers, so you need an approximate test for equality.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2006
    Posts
    102
    Rep Power
    8
    lol more noob at this than I thought!
    Just tested more and it doesn't work, sry :o
  8. #5
  9. BANDITS 6'0 Clock !
    Devshed Novice (500 - 999 posts)

    Join Date
    Aug 2006
    Location
    at the top of the stairway to heaven.
    Posts
    729
    Rep Power
    232
    Well you could change your teminating condition! and that depends on how accurate you want the result to be, my guess is for sin(x);
    computing beyond n = 5 (the fifth expression is futile ), this is mainlybecause your remainder is a factorial term (which is exponential ) so what happens is the fraction becomes so small that it contributes to the real number (the value of sin(x) ) very far away from the deciaml place!

    e.g. 1/(10!) = 2.7557319223985890652557319223986e-7
    that .000000275555...

    and the numerator is obviously in radians!
    using series expansion till the third element ( till 5!)
    sin(Pi/4) = .70687 which is very close to sin (45) = 1/sqrt(2);
    So in the End how accurate do you want it to be ?
    p.s Pi/4 for radians ( Pi = 3.14)
    The only Verdict is Vengeance a Vendetta held as a Votive, not in Vain, for the Value and Veracity of such shall one day Vindicate the Vigilant and the Virtuous


    Mav RLZ AC/DC RLZ
  10. #6
  11. ASP.Net MVP
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Aug 2003
    Location
    WI
    Posts
    4,378
    Rep Power
    1510
    Wow, brings back memories. I remember programming what I think was taylor series into my casio graphing calculator in high school so I could check my work on tests (note: not actually do the work, just check it), and programming it in fortran in college for a numerical computing class.
    Primary Forum: .Net Development
    Holy cow, I'm now an ASP.Net MVP!

    [Moving to ASP.Net] | [.Net Dos and Don't for VB6 Programmers]

    http://twitter.com/jcoehoorn
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2006
    Posts
    24
    Rep Power
    0
    Thx a lot dudes.....
    How accurate.. ?? Lets say accurate enough to compare it with a casio fx series hand calculator.

    Well i am wandering if i write the above program in perl what the results would be. (lets check it out)

    Thx
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    How accurate? Well, the series converges because eventually the terms become vanishingly small. So figure how accurate you want it and test for when the new term is smaller than that.

    However, because of the inherent limitations of the floating-point representation you will need to choose a test value that can still be represented by a double.

    But also, wouldn't Horner's Rule come into play? It's been nearly three decades so I might not remember correctly, but if you're summing a polynomial (which is basically what a series is, IIRC) then you need to start with the smallest terms first. If you instead start with the largest terms, then when you add the smallest terms it would be as if you were adding zero.

    This would mean that in choosing the smallest term that you could add that you would need to consider the mantissa more closely than the exponent. Unless you can figure out a way to use Horner's Rule.


    PS
    OK, I didn't quite remember correctly (http://en.wikipedia.org/wiki/Horner%27s_rule).

    However, there is still the issue of trying to add a small-magnitude term to a large-magnitude sum.
    Last edited by dwise1_aol; February 13th, 2007 at 11:19 AM.
  16. #9
  17. BANDITS 6'0 Clock !
    Devshed Novice (500 - 999 posts)

    Join Date
    Aug 2006
    Location
    at the top of the stairway to heaven.
    Posts
    729
    Rep Power
    232
    Originally Posted by Linuxlover0101
    Thx a lot dudes.....
    How accurate.. ?? Lets say accurate enough to compare it with a casio fx series hand calculator.

    Well i am wandering if i write the above program in perl what the results would be. (lets check it out)

    Thx
    well I have a 991 MS and that is one of the latermodels I think, and it has precision till nine decimal places !

    and one point to think ...
    1/3 = .333333333333
    1/5 = .2

    so instead of fixing on number of decimal places, I would suggest you limit your accuracy based on the number of interations, and then round up to how many decimal places u want!

    And like I said before
    sin(Pi/4) = .706861317 till the third term in the series ( that is till 5! ) which is very close to 1/sqrt(2) = .707106781,
    In other words the former is accurate till the fourth decimal place ( if you round it up mathematically)

    So just experiment with the number of iterations till you get the level of accuracy you require.
    The only Verdict is Vengeance a Vendetta held as a Votive, not in Vain, for the Value and Veracity of such shall one day Vindicate the Vigilant and the Virtuous


    Mav RLZ AC/DC RLZ
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2006
    Posts
    271
    Rep Power
    15
    As mentioned previously, comparing floating point numbers for equality is a bad idea.

    If you have an IEEE 754 compliant system, the compiler is very likely defaulting the internal precision control of the math unit to the 80-bit temp real format, but your memory format is the 32 bit short real - IOW bits get lost on a memory store out of the FP unit for both floats and doubles and stay lost forever.
  20. #11
  21. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,379
    Rep Power
    1871
    > IOW bits get lost on a memory store out of the FP unit for both floats and doubles and stay lost forever.
    Absolutely!
    Some time ago, this thread on another board was about that very issue.
    Changing the code changed the ability of the compiler to keep values in floating point registers (and thus changed the result).

    It took 20 replies to finally convince them that there was really a problem with comparing floats for equality.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2006
    Posts
    271
    Rep Power
    15
    It was just a lucky guess Salem - I'm just a "moron" :D

IMN logo majestic logo threadwatch logo seochat tools logo