QNA > C > Come Fa Una Calcolatrice A Trovare Il Valore Del Coseno Di Un Angolo? Viene Semplicemente Salvato Nella Calcolatrice?

Come fa una calcolatrice a trovare il valore del coseno di un angolo? Viene semplicemente salvato nella calcolatrice?

Sì, alcune calcolatrici potrebbero usare una tabella di Lookup per ottenere la risposta, o almeno una parte di essa.

Ma il coseno può essere calcolato con precisione crescente calcolando e sommando sempre più termini della sua serie di Taylor

main-qimg-4ab458db420ee290906af0af848dbd94


Ho fatto un piccolo grafico che mostra le prime iterazioni di applicazione di questa serie:

main-qimg-784fbf8972570595c29f67429ac3caf1.webp


Questo è un coseno centrato sull'origine. La linea nera tratteggiata è un coseno reale.

rosso = 1 iterazione (max k = 0)
verde = 2 iterazioni (max k = 1)
blu = 3 iterazioni (max k = 2)
magenta = 4 iterazioni (max k = 3)
ciano = 5 iterazioni (max k = 4)

Come potete vedere, si avvicina sempre più al valore reale del coseno. If we carried it on to infinity it would exactly match.

But you can see, even after just a handful of iterations, it is very closely matching the real shape up to where it first crosses the x-axis (where x = pi/2). And that's all we need, because the rest of the wave can be constructed by reversing it (horizontally and vertically), which is very easily done in code.

I would guess that the first few values of ((-1)^k)/(2k)! are stored in a lookup table for optimisation.

Edit: Okay, I got interested in the challenge and wrote a little cosine function of my own, using the taylor expansion.

  1. int NUM_ITERATIONS = 3;  
  2. float[] LUT = new float[NUM_ITERATIONS]; 
  3.  
  4. int factorial(int k) {  
  5. int f = 1;  
  6. k++;  
  7. while (k-->1) f *= k;  
  8. return f; 
  9.  
  10. void setupLUT() {  
  11. for (int k=0; k
  12. LUT[k] = pow(-1.0,k) / factorial(k*2); 
  13.  
  14. float taylorSeries(float x) {  
  15. float f = 0;  
  16. for (int k=0; k
  17. f += pow(x,k*2.0) * LUT[k];  
  18. return f; 
  19.  
  20. float myCosine(float x) { 
  21. x = abs(x) % TWO_PI; 
  22. if ( x>PI ) x = TWO_PI-x; 
  23. return (x

It's surprisingly accurate, even with only 3 iterations:

main-qimg-df23380a5c17dc1dc2fcd752eda51105.webp

Di Philippine Maulsby

Qual è la complessità temporale dell'algoritmo GCD di Euclide? :: Qual è la derivata di (500/x)?
Link utili