La fonction sinus à l'aide de développement de Taylor (Programmation en C)
Ici est la question..
C'est ce que j'ai fait jusqu'à présent,
#include <stdio.h>
#include <math.h>
long int factorial(int m)
{
if (m==0 || m==1) return (1);
else return (m*factorial(m-1));
}
double power(double x,int n)
{
double val=1;
int i;
for (i=1;i<=n;i++)
{
val*=x;
}
return val;
}
double sine(double x)
{
int n;
double val=0;
for (n=0;n<8;n++)
{
double p = power(-1,n);
double px = power(x,2*n+1);
long fac = factorial(2*n+1);
val += p * px / fac;
}
return val;
}
int main()
{
double x;
printf("Enter angles in degrees: ");
scanf("%lf",&x);
printf("\nValue of sine of %.2f is %.2lf\n",x,sine(x * M_PI / 180));
printf("\nValue of sine of %.2f from library function is %.2lf\n",x,sin(x * M_PI / 180));
return 0;
}
Le problème est que le programme fonctionne parfaitement bien de 0 à 180 degrés, mais au-delà de ce qu'elle donne à l'erreur.. Aussi quand j'augmente la valeur de n
dans for (n=0;n<8;n++)
au-delà de 8, j'obtiens des erreurs.. Il n'y a rien de mal avec l'algorithme, je l'ai testé dans ma calculatrice, et le programme semble être très bien.. je pense que le problème est dû à la plage du type de données.. que dois-je corriger pour se débarrasser de cette erreur?
Merci..
- Quelle est l'erreur exactement?
- Je ne sais pas pour vous si c'est ça, mais tu parlais de type de données plage de... Avez-vous essayé d'avoir
factorial
retour d'unlong long int
? - la valeur diffère de la valeur standard.. par exemple à 270 degrés-je obtenir -0.44, mais la valeur standard est de -1.
- oui, essayé.. n'a pas aidé..
- (Je suppose que vous voulez dire "de 0 à pi" plutôt que "de 0 à 180 degrés", parce que le développement de Taylor travaille en radians, pas de degrés). Vous avez besoin pour réduire l'ampleur de la
px
etfac
variables. Par exemple, refactoriser l'expression de x^(2n+1)/(2n+1)! le produit(i=1 étape 2 à 2n+1){x/j'ai}. Notez également que la convergence est lente lorsque vous obtenez loin de 0. - Il fait la conversion en radians.
Vous devez vous connecter pour publier un commentaire.
Il est exact que l'erreur est due à la plage du type de données. Dans les sinus(), vous êtes le calcul de la factorielle de 15, ce qui est un chiffre énorme et ne rentre pas en 32 bits (ce qui est probablement ce long int est mis en œuvre que sur votre système). Pour résoudre ce problème, vous pouvez soit:
long int
type de retour defactorial
àdouble
, ainsi que lalong
type de stockage defac
àdouble
?15!
est en effet au-delà de gamme qu'un entier 32 bits peut contenir. J'aimerais utiliser des doubles tout au long si j'étais vous.La série de taylor pour
sin(x)
converge plus lentement pour les grandes valeurs de x. Pour x-hors-π,π. Je voudrais ajouter/soustraire des multiples de 2*π pour obtenir un x que possible.Vous pouvez peut-être avoir un problème avec 15!.
Je voudrais imprimer les valeurs de p, px, fac, et la valeur de la durée pour chaque itération, et de les vérifier.
Vous êtes seulement, dont 8 en une série infinie. Si vous pensez à ce sujet pendant une seconde en termes d'un polynôme, vous devriez voir que vous n'avez pas un assez bon ajustement pour l'ensemble de la courbe.
Le fait est que vous avez seulement besoin d'écrire la fonction pour 0 <= x <=\pi; toutes les autres valeurs à suivre à l'aide de ces relations:
et
et
Je vous recommande de normaliser votre entrée à l'angle de l'utilisation de ces à faire de votre fonction de travail pour tous les angles comme écrit.
Il y a beaucoup d'inefficacité intégré dans votre code (par exemple, vous gardez le recalcul des factorielles qui pourrait facilement s'insérer dans une table de recherche; vous utilisez l'alimentation() pour oscillent entre -1 et +1). Mais assurez-vous qu'il fonctionne correctement, alors le rendre plus rapide.
0 to 8
sur ma calculatrice.. et pour des angles plus élevés, même sans l'aide de la trigonométriques manipulations..Vous avez besoin de réduire la portée. Notez qu'un développement en série de Taylor est le meilleur proche de zéro et que, dans la plage négative c'est l' (négatif) miroir une image positive de la gamme. Donc, en bref: réduire la portée (par le modula de 2 PI) pour envelopper la plage où vous avez la plus grande précision. La gamme au-delà de 1/2 PI est moins précis, si vous souhaitez également utiliser la formule suivante: sin(1/2 PI + x) = sin(1/2 PI - x). Pour le négatif, vales utiliser la formule suivante: sin(-x) = -sin(x). Maintenant vous avez seulement besoin d'évaluer l'intervalle 0 - 1/2 PI tout en couvrant l'ensemble de la gamme. Bien sûr, pour de TRÈS grandes valeurs de la précision de la modula de 2 PI va en souffrir.