6
votes

Meilleure approximation de e avec java

Je voudrais approximer la valeur de E à toute précision souhaitée. Quelle est la meilleure façon de procéder? Le plus que j'ai pu obtenir est E = 2.7182818284590455. Tous les exemples sur une modification du code suivant seraient appréciés.

public static long fact(int x){
    long prod = 1;
    for(int i = 1; i <= x; i++)
        prod = prod * i;
    return prod;
}//fact

public static void main(String[] args) {
    double e = 1;
    for(int i = 1; i < 50; i++)
        e = e + 1/(double)(fact(i));
    System.out.print("e = " + e);
}//main


2 commentaires

Évidemment, un double ne peut jamais contenir plus de chiffres que sa précision. Utilisez un type de nombre différent.


Beaucoup ce que Joren a dit. L'idée de "toute précision souhaitée" est fondamentalement incompatible avec le calcul dans un type à largeur fixe.


8 Réponses :


13
votes

Utilisez un BigDecimal au lieu d'un Double. XXX


5 commentaires

La mise en œuvre de cela a donné à l'exécution: exception dans le fil "Main" Java.Lang.Arithméticepxception: expansion décimale non terminée; pas de résultat décimal représentable exact. Est-ce que quelque chose manque?


Pardon. La division a besoin d'une image arrondi, sinon BigDecimal se jette lorsque vous voyez 1/3. Corrigé ça.


Comment utiliser cela? Je fais System.out.println (E) après la boucle et obtenez 3


@FLYBYWIRE: La précision n'a pas été définie, corrigée aussi. Cette fois, j'ai aussi essayé de diriger le code avant de "publier" ça :).


Comment faire fonctionner une fonction avec un paramètre pour le nombre de chiffres? J'ai essayé d'utiliser la boucle pour la boucle mais cela n'a pas fonctionné. Pourrais-tu m'aider s'il te plait?



3
votes

Vous obtiendrez de meilleurs résultats si vous comptez de 49 à 1 au lieu de 1 à 49 comme maintenant.


0 commentaires

6
votes

Votre problème principal est que double a une précision très limitée. Si vous voulez une précision arbitraire, vous devrez utiliser bigdecimal . Le problème suivant que vous allez courir est la plage limitée de long que vous allez dépasser très rapidement avec la factorielle - vous pouvez utiliser biginteger .


0 commentaires

4
votes

Avez-vous consulté l'arithmétique arbitraire de précision dans java.util.bigdecimal ? XXX


0 commentaires

0
votes

Pour comprendre pourquoi vous ne pouvez pas obtenir "aucune précision souhaitée" avec double , lire ce papier classique:

Ce que chaque scientifique informatique devrait connaître sur l'arithmétique de point flottant

Notez que c'est un document assez technique. Pour plus de détails sur la manière dont les numéros de points flottants fonctionnent, voir cet article Wikipedia: Double précision Point flottant Format


0 commentaires

1
votes

est allé avec une variation du code de Zed and Mobrule. Fonctionne génial, merci! Plus de conseils de performance quiconque? XXX


2 commentaires

Conseil de performance: Arrêtez de recalculer le factoriel. Utilisez la solution de ZED où vous faites "faits = fait.Multiphe (nouveau bigdecimal (i))" dans la boucle, au lieu de le calculer à nouveau.


À titre de preuve, la solution de Mobrule fonctionne dans 542 ms, votre version s'exécute en 858ms pour 1000 itérations.



1
votes

Plus de conseils de performance n'importe qui?

Oui, votre calcul de factorielle est aussi inefficace que possible. Il serait préférable de déplacer cela à l'intérieur de la boucle où vous sommez les termes. La façon dont vous faites les choses transforme un problème O (n) dans un problème O (n ^ 2).

Et s'il s'agissait d'un calcul réel qui nécessitait des facteurs facteurs, je recommanderais une recherche de table ou la fonction gamma incomplète comme la bonne façon de le faire.

La seule chose que vous auriez pu faire pire d'un point de vue de la performance est un calcul factorial récursif. Ensuite, vous auriez le problème supplémentaire d'une immense pile.


0 commentaires

0
votes

La meilleure approximation de E peut être obtenue à l'aide de la classe BigDecimal.

Voici le code de calcul de la valeur BigDecimale donnée xxx

retourne: xxx

la valeur de f est xxx

la valeur de E est xxx


0 commentaires