High precision sine

Started by
8 comments, last by toxigun 22 years, 1 month ago
I am looking for a way to calculate sine with a very high precisoin. the normal sin() function is not enough. 10x in advance.
Advertisement
how precise do you need it? you might need to use some special number class to get really precise numbers (unless there is some kind of 64bit float representation?) anyway, you can calculate sine to arbitrary precision using the infinite series:
    x^3   x^5                 x^(2n+1)x - --- + --- ... + (-1)^n * ---------     3!    5!                  (2n+1)! 
(may have to edit that to make it come out clearer

anyway, since its an alternating series, you are guaranteed the error will be less than the value of the next term, so you can figure out when to stop. however, doing it this way will probably be extremely expensive. you could probably save some processing by being clever about caching the values of the powers (like save x^2, and each time, just multiply the numerator by that so that you have the next numerator, and save the factorial and you get only two mults.. totaling 3 mults, a div and an add per term.

hope that helps,

ewen
you mean
sin(x) = the_series_you_have_written

?
yeah, sorry if that wasn''t clear. in case it is of any interest, cosine is very similar to that:
             x^2   x^4                x^(2n)cos(x) = 1 - --- + --- + ... (-1)^n * ------             2!    4!                  (2n)! 


and similar caching tricks would work here as well. as i said before though, you need some really precise type. if you need a refresher on infinite series, i can either find one for you or make a little one up.

Myopic Rhino: if you read this, has any real effort been made to collect all these tidbits? we both answered that thing about loops before too, but you gave a really nice long, detailed, robust answer which would be a good for new people. the same problem where people don''t look before asking would arise, but then people wouldn''t need to repeat the same posts over and over. just a thought.

ewen
quote:Original post by echeslack
Myopic Rhino: if you read this, has any real effort been made to collect all these tidbits?

I think that''s a brilliant idea and will further it to the mods when I get back to my machine.

quote:we both answered that thing about loops before too, but you gave a really nice long, detailed, robust answer which would be a good for new people.

Not that I mind, but that was me, not Dave.

[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
hey guys what do u think of this cosine i wrote from series
im proud of it


  double _cos(double x){ register double res; register double m0,m1,m2,m3; m0 = x*x;//2 m1 = m0*m0;//4 m2 = m1*m0;//6 m3 = m2*m2;//12 res  = cos_table[0]+	    m0*cos_table[1]+	    m1*cos_table[2]+		m2*cos_table[3]+		m2*m0*cos_table[4]+		m2*m1*cos_table[5]+		m3*cos_table[6]+		m3*m0*cos_table[7]+		m3*m1*cos_table[8]+		m3*m2*cos_table[9]+		m3*m2*m0*cos_table[10]+		m3*m2*m1*cos_table[11]; return res;}  


if u dont know what cos_table is dont reply
> hey guys what do u think of this cosine i wrote from series

You can improve on it by more careful choice and use of variables, e.g.


  double _cos(double x){ double sum; double m2,mn; m2 = x*x; sum = cos_table[0]; sum += m2 * cos_table[1]; mn = m2 * m2; sum += mn * cos_table[2]; mn = mn * m2; sum += mn * cos_table[3]; mn = mn * m2; sum += mn * cos_table[4]; mn = mn * m2; sum += mn * cos_table[5]; mn = mn * m2; sum += mn * cos_table[6]; mn = mn * m2; sum += mn * cos_table[7]; mn = mn * m2; sum += mn * cos_table[8]; mn = mn * m2; sum += mn * cos_table[9]; mn = mn * m2; sum += mn * cos_table[10]; mn = mn * m2; sum += mn * cos_table[11]; return sum;}  


This has fewer multplications and needs fewer variables. I would not bother with ''register'': a decent compiler will make its own mind up about this.

If a function like this is used repeatedly it may be worth re-writing in assembler, but first look at the assembler outpur produced by your compiler, as with well written high-level code it''s often difficult to improve on it.
John BlackburneProgrammer, The Pitbull Syndicate
johnb:
true your way has 22 multiplications and mine has 24,
not much difference

and besides that yours has many ''mov'' instructions
you are assigning mn a value each time which is not good
also mine has 5 variables while urs has 3
also not much difference since im aiming at speed optimizing

this is my opinion no disrespecting intended.

> and besides that yours has many ''mov'' instructions
> you are assigning mn a value each time which is not good

It has no extra ''mov'' instructions. Each time a processor does a multiply it has to put the result somewhere. Yours are less obvious because of the way you''ve written the code, but there''s one assignment for each * so there are more in your code.

Again if you''re really interested in how many ''mov'' instructions there are it may be worth coding in assembler, but first check the output of your compiler as a good compiler will turn well-written source into code you''ll find it difficult to improve on.
John BlackburneProgrammer, The Pitbull Syndicate
ok johnb i have counted the floating point operations on both functions

urs has 61 and mine has 50

and i timed both, mine gave faster results when the load is increased(if u know what i mean)

if you dont believe me check it all your self

This topic is closed to new replies.

Advertisement