En general, para que las rutinas que se utilizan una y otra vez, como aquellas para las funciones trigonométricas, las calculadoras y las computadoras tienen una tabla de valores precalculados y las usan para generar otros valores. Los detalles de este dependen del problema. Un sistema común es utilizar el polinomio de interpolación o trozos polinomio de interpolación de los valores calculados de las funciones deseadas. El algoritmo CORDIC se utiliza a menudo para funciones trigonométricas en particular, y no otra cosa, que es bien discutido en el artículo de la Wikipedia. Tal vez esto es de interés para usted, pero siempre me parece un poco insatisfactorio cuando me estas respuestas, ya que por lo general no dicen donde el precalculadas valores de vino.
Aquí es un simple algoritmo para el cálculo de $\sin$, con poco precomputing necesario. Se basa en la aproximación de Taylor. Para hacerlo funcionar, usted necesita saber $\pi$, y también necesitamos precompute la serie de Taylor términos que se utilizarán. El último se discute a continuación.
En primer lugar vamos a utilizar algunas identidades trigonométricas básicas para reducir a una función sin1 que se limita al primer cuadrante. (Esto está escrito en Matlab sintaxis).
function y=mysin(x)
z=mod(x,2*pi);
if 3*pi/2<=z
y=-sin1(2*pi-z);
elseif pi<=z
y=-sin1(z-pi);
elseif pi/2<=z
y=sin1(pi-z);
else
y=sin1(z);
end
Ahora vamos a reducir de que para la primera mitad del primer cuadrante. Lo que podemos hacer sólo la informática coseno después de reflexionar a través de la línea de $y=x$.
function y=sin1(x)
if x>pi/4
y=cos1(pi/2-x);
return
end
Así que vamos a tratar con los que no necesitan reducirse coseno. Aquí Taylor teorema nos dice
$$\sin(x)=\sum_{n=0}^N \frac{(-1)^n x^{2n+1}}{(2n+1)!} + R_N$$
where $|R_N| \leq \frac{|x|^{2N+2}}{(2N+2)!}$. So we need to identify $N$ such that $\frac{|\pi/4|^{2N+2}}{(2N+2)!}<10^{-16}$ (around the usual error tolerance for IEEE double precision). Just directly checking some values reveals that it is enough to take $N=8$. So we can finish the second half of our "sin1" function like this:
n=0:8;
m=2*n+1;
y=sum((-1).^n.*x.^(m)./factorial(m));
Then you can do basically the same thing to define cos1, to finish the overall problem:
function y=cos1(x)
n=0:8;
m=2*n;
y=sum((-1).^n.*x.^(m)./factorial(m));
Note that this can be made considerably more efficient without actually changing the mathematical character of it by precomputing the coefficients and evaluating the polynomial using Horner's method.
Note that not all the reductions that I did here were strictly necessary. We do need to reduce to one period (otherwise the method would need to dynamically choose $N$ and would be very slow for large arguments). But if we do that and don't reduce to the first quadrant, we can just raise $N$ to $20$. Alternately, we could just reduce to the first quadrant itself and stop, provided we raise $N$ to $11$.
También, he probado la de arriba un poco. Se desvía un poco de Matlab de la función sin grandes argumentos; por ejemplo pecado(50000)= -0.999840189089790 y mysin(50000)= -0.999840189089824. El problema parece estar totalmente causado por error aritmético en el primer paso, ya que (en Matlab) pecado(mod(50000,2*pi))==mysin(50000). Tal vez alguien podría comentar sobre una buena manera de arreglar esto?