PDA

View Full Version : [C] Calcolo del seno


Leonerd
25-01-2015, 10:31
Ciao a tutti.

Mi sono posto un problema: come fanno le calcolatrici a calcolare il seno e il coseno di qualsiasi numero preso in input? In pratica mi chiedevo come fossero implementate le funzioni del calcolo del seno e del coseno all'interno di math.h per cercare di rifarle, perchè, conosciuto il valore di un angolo, non riesco ad arrivare al seno solo gemetricamente (senza utilizzare ovviamente teoremi vari come il teorema della corda che include il seno stesso dell'angolo).

Riuscite ad aiutarmi?

DoctorT
25-01-2015, 15:56
come fanno le calcolatrici esattamente non lo so ma un metodo di calcolo numerico c'è.

Mai come in questo caso google is your friend: http://www.luigisirignano.it/index.php?option=com_jdownloads&Itemid=0&view=viewcategory&catid=266

ho il sospetto che ci sia un metodo iterativo meno "pesante" dal punto di vista computazionale ma non sono riuscito a trovarlo

lorenzo001
25-01-2015, 21:53
Dai un'occhiata a questa implementazione


double mysin(double x, size_t number_of_terms)
{
const double x2 = x * x;

double t = x;
double result = t;

for (size_t i = 1; i < number_of_terms; ++i)
{
t = t * x2 / (double(2*i) * double(2*i+1));
if (i % 2 == 0) result += t;
else result -= t;
}

return result;
}


e usala calcolando 9 termini con

v = mysin(arg, 9);

lorenzo001
26-01-2015, 11:22
Per ottimizzare e velocizzare aumentando la precisione, è possibile precalcolare il valore nella prima espressione e utilizzare una tabella più ampia; inoltre è possibile gestire un'altra variabile per il segno.

In pratica


#include <math.h>

double mysin(double x)
{
const double x2 = x * x;
const double tb[] = {6.0, 20.0, 42.0, 72.0, 110.0, 156.0, 210.0, 272.0, 342.0, 420.0, 506.0, 600.0, 702.0};

double t = x;
double result = t;
double sg = -1.0;

for (size_t i = 0; i<13; ++i)
{
t *= x2 / tb[i];
result += sg * t;
sg = -sg;
}

return result;
}

int main()
{
double arg;

for(arg=0.0; arg<3.1415; arg+=3.1515/20)
printf("%.15f %.15f\n", mysin(arg), sin(arg));
return 0;
}


Nota che nel codice viene utilizzato un ciclo con un intero e le semplici operazioni in virgola mobile.

ingframin
26-01-2015, 11:52
Nel passato usavano questo metodo, ma non sono sicuro sia ancora usato dalle calcolatrici.
http://en.wikipedia.org/wiki/CORDIC

Il CORDIC era un chip che poteva essere usato per seni e coseni, tangenti e arcotangenti, funzioni iperboliche e radice quadrata di un numero.
Fu fatto per sostituire un circuito analogico che al tempo veniva usato per le stesse cose.

Per le nuove sono propenso a dare ragione ad Antonio, fare moltiplicatori e divisori al giorno d'oggi non è più una roba complessissima come lo era 50 anni fa.

lorenzo001
26-01-2015, 12:14
Non ho indicato quel codice per dire che lo usano le calcolatrici ma solamente per suggerire un modo "semplice" di calcolare il seno, facendo a meno di elaborare potenze.

Se non mi sbaglio, era il metodo usato nel "vecchio" Commodore 64.

Daniels118
26-01-2015, 14:17
Se sei curioso, ti consiglio di dare uno sguardo qui: http://rosettacode.org/wiki/Trigonometric_functions#REXX
Non è in c, ma gli algoritmi si possono implementare in qualunque linguaggio.