cs_orelec
Messages postés7Date d'inscriptiondimanche 4 juin 2006StatutMembreDernière intervention15 octobre 2006 12 oct. 2006 à 18:57
Grosse erreur de ma part :
double * int = double
Une ligne a été coupée involontairement :
double * long = long
cs_orelec
Messages postés7Date d'inscriptiondimanche 4 juin 2006StatutMembreDernière intervention15 octobre 2006 12 oct. 2006 à 18:54
BidDecimal et BigInteger (classe java.math) ne contiennent aucune méthode de trigonométrie.
Pour la factorielle, un long est plus approprié qu'un double : dans un calcul avec deux types primitifs différents (un entier et un décimal) le résultat est du type de celui qui est décimal (on a soit un bug sur le type à la compillation, soit on utilise un cast).
Exemples :
float * int = float
double * int = long
On a également dans ces cas une erreur liée à l'approximation.
Dans le cas de la factorielle, on ne peut que dépasser les valeurs suivantes :
int : 12!
long : 20!
Au dessus pour une précision à l'unité, il faut utiliser la classe java.Math.BigInteger. En sachant également que le nombre de zéros est le suivant :
zéros = Math.floor(exposant / 5)
Formule qui permet de calculer la factorielle en utilisant les propriétés de calcul avec des puissances
targ
Messages postés1Date d'inscriptionsamedi 13 septembre 2003StatutMembreDernière intervention26 avril 2006 26 avril 2006 à 09:19
Un simple petit tour sur google t'aurais permis de constater qu'il existe déjà une fonction arcsin dans J2ME (Math.asin) qui est surement bien plus rapide que ta fonction.
Pole4
Messages postés20Date d'inscriptionmardi 11 octobre 2005StatutMembreDernière intervention13 mars 2007 24 oct. 2005 à 11:39
J'ai oublié pour la fonction de pochhammer :
on peut aussi s'en passer
une variable mis à 0.5 et à chaque boucle on multiplie par 0.5+k
Je verrais bien le début comme ça :
private double arcsin(double z) {
int k,i;
int N = 30; // This number determines the precision, higher it is, higher the precision is.
double res,tmp1,tmp2,tmp3,facto;
res = 0;
if (Math.abs(z)<=0.5) {
// = sum(k=0 a n) de (produit de j=0 a k-1 de (0.5+j))*z exp 2k+1) div (k! * k+1)
tmp2=z;tmp3=1;facto=1;
for (k=0;k<N;k++) {
tmp3 *= 0.5+k; // tmp3=prod(0.5,k)
tmp1 =tmp3*tmp2;
tmp1 /= (2*k+1);
tmp1 /= facto;
tmp2 *= z*z; // c'est le 2*k+1 de la boucle
if (k!=0) facto *=k; // facto=fact(k)
res += tmp1;
}
} else if (z>0.5) {
Voilà. Pour la suite change le "tmp2 *= z*z;" en "tmp2 *= z;".
(Je n'ai pas compilé le code, donc il peut y avoir des erreurs)
Pole4
Messages postés20Date d'inscriptionmardi 11 octobre 2005StatutMembreDernière intervention13 mars 2007 24 oct. 2005 à 11:19
Juste pour l'optimisation (si tu veux avoir quelques milliers de décimales) :
tmp1 /= fact(k);
tu peux mettre une variable que tu multiplie à chaque fois dans la boucle.
for (i=0;i<k;i++)
tmp2 *= ((z+1)/2);
même chose
Mais ces améliorations ne servent à rien si tu te sers que de 7 où 16 décimales.
Par contre, pour les BigDecimal, ça peut servir. (Il y a peut être une fonction arcsin dans la bibliothèque de BigDecimal, mais bon)
12 oct. 2006 à 18:57
double * int = double
Une ligne a été coupée involontairement :
double * long = long
12 oct. 2006 à 18:54
Pour la factorielle, un long est plus approprié qu'un double : dans un calcul avec deux types primitifs différents (un entier et un décimal) le résultat est du type de celui qui est décimal (on a soit un bug sur le type à la compillation, soit on utilise un cast).
Exemples :
float * int = float
double * int = long
On a également dans ces cas une erreur liée à l'approximation.
Dans le cas de la factorielle, on ne peut que dépasser les valeurs suivantes :
int : 12!
long : 20!
Au dessus pour une précision à l'unité, il faut utiliser la classe java.Math.BigInteger. En sachant également que le nombre de zéros est le suivant :
zéros = Math.floor(exposant / 5)
Formule qui permet de calculer la factorielle en utilisant les propriétés de calcul avec des puissances
26 avril 2006 à 09:19
24 oct. 2005 à 11:39
on peut aussi s'en passer
une variable mis à 0.5 et à chaque boucle on multiplie par 0.5+k
Je verrais bien le début comme ça :
private double arcsin(double z) {
int k,i;
int N = 30; // This number determines the precision, higher it is, higher the precision is.
double res,tmp1,tmp2,tmp3,facto;
res = 0;
if (Math.abs(z)<=0.5) {
// = sum(k=0 a n) de (produit de j=0 a k-1 de (0.5+j))*z exp 2k+1) div (k! * k+1)
tmp2=z;tmp3=1;facto=1;
for (k=0;k<N;k++) {
tmp3 *= 0.5+k; // tmp3=prod(0.5,k)
tmp1 =tmp3*tmp2;
tmp1 /= (2*k+1);
tmp1 /= facto;
tmp2 *= z*z; // c'est le 2*k+1 de la boucle
if (k!=0) facto *=k; // facto=fact(k)
res += tmp1;
}
} else if (z>0.5) {
Voilà. Pour la suite change le "tmp2 *= z*z;" en "tmp2 *= z;".
(Je n'ai pas compilé le code, donc il peut y avoir des erreurs)
24 oct. 2005 à 11:19
tmp1 /= fact(k);
tu peux mettre une variable que tu multiplie à chaque fois dans la boucle.
for (i=0;i<k;i++)
tmp2 *= ((z+1)/2);
même chose
Mais ces améliorations ne servent à rien si tu te sers que de 7 où 16 décimales.
Par contre, pour les BigDecimal, ça peut servir. (Il y a peut être une fonction arcsin dans la bibliothèque de BigDecimal, mais bon)