File : Sincos.tut
Date : 7.2.1997
Author : [CrY0] / Quasar
Email : uzs3e7@ibm.rhrz.uni-bonn.de
Description : Fast sin and cos calculations using Euler's formula.
Source code : Borland / Turbo C++ 3.1.
[Intr0]
Hi folks, [CrY0] here. Actually i don't know how many people will ever need
to do real time sin and cos calculations, since almost everything can be done
with tables. At least, that's what i thought, but yesterday i met Kory on IRC
channel #coders, and he really needed to do that for a prog. he was coding. So
i called up on my math knowledge and came up with a quite quick method to do
the job, at least, as long as you don't mind having accuracy losses. :)
I know many others have done this before, it is nothing new, but you can always
use another tutor, right?
[MatH]
Ok, if you have had higher trig, and you know what a sum ( represented by the
greek letter Sigma ) and the constane e is, then skip this part and go
straight for the source code later on the text.
The method i will explain here is based on Euler's formula.
First, we need to define some stuff and notation:
a)
n
n! = ô k = 1*2*3*...*n
k=1
example: 4! = 1*2*3*4 = 24
b) ( Where E means 'the sum of' , i couldnt find Sigma on my keyboard :) )
1
e = E --- = Euler's number. This is a constant. The value is not
n=0 n! of interest for us now, so just read on :)
c) Euler's Formula:
i*x
e = cos x + i*sin x where i is the square root of -1 (complex).
Now we can use b) and write Euler's formula like this:
n 2*k
i*x (i*x) n x k x
e = E ------- = E i * ------ E (-1) * ------
n=0 n! n=0 n! k=0 (2*k)!
2*k+1
k x
+ i * E (-1) --------
k=0 (2*k+1)!
We see that we splitted the first sum into two sums. We notice too that the
in the first sum we have the even numbers and in the secont the odd numbers in
the power of x, 2*k and 2*k+1. Further, we see that the first sub-sum (i like
that word :) ) is real, and the second is complex.
Now if we look at c), we see that cos x is real part and i*sin x the complex
one. Ok, made 'click' already??
Allright, i dont want to bore you with the math stuff anymore, so ill go
straight to the interesting part.
2*k 2 4 6
k x x x x
cos x = E (-1) ------ = 1 - ---- + ---- - ---- + ...
k=0 (2*k)! 2! 4! 6!
2*k+1 3 5 7
k x x x x
sin x = E (-1) ------ = x - ---- + ---- - ---- + ...
k=0 (2*k+1)! 3! 5! 7!
Ok? That's fine, i hear you say, but how does that improve my sexual life???
It doesnt improve your sexual life, but your code can be made pretty fast.
Isnt that the real important thing?? :)
[C0De]
Let's try to set up a little piece of code that will do the job. I will begin
with lame floating-point-using C code, and move down to fast fixed point
arithmetic in pure ASM. ( Note: that will be on a separated file ).
#include
#include // We need this to compare our results with the real sin()
// and cos() functions.
// Besides, we need the pow() function.
void main()
{
float result;
float x;
printf("\nEnter x: " ); // x is the number whose sinus you want to
// calculate.
scanf( "%f", &x ); // Enter x.
result = x - pow( x, 3 ) / 6; // Do it!
// Check our result with math.h's sin() function.
printf( "\nOur result : %f", result );
printf( "\nmath.h's result : %f", sin( x ) );
}
Try it with many values, and you will see that it is not very accurate, but it
is fast. If you need more accuracy, then you must do the following:
result = x - pow( x, 3 )/6 + pow( x, 5 )/120 - pow( x, 7 )/5040 ...
Where 6 = 3!, 120 = 5!, 5040 = 7! ...
Ok? Now go ahead and try the cosine for yourself!
Well, thats all for now, next week ill finish the assembler part of this tutor,
so stay tuned!
[GrReEtZ]
A tutor can't be complete without the greetings part, so here i go:
- Mega Greetz to my demo group, QUASAR.
- Special Greetz to Kory for making me write this in the first place :)
- Cool greetz to: tig2, zylon, debonair, barog, RuneStar, CRShadow, iitm,
X, RyanT, Scorpio, Frenzy, luvscrs, Kaneda, Killgates, jungle, and
everyone else in Undernet #coders i forget, you guys rule!!!
For bugs, flames, marriage proposals or just for fun, email me at the above
address.
[E0f]