2

Je voudrais calculer (1.0-p)^n où p est un double entre 0 et 1 (souvent très proche de 0) et n est un entier positif qui pourrait être de l'ordre de centaines ou de milliers (peut-être plus grand, je ne suis pas encore sûr). Si possible, j'adorerais simplement utiliser Java java.lang.Math.pow(1.0-p, n) pour cela, mais je suis légèrement préoccupé par le fait qu'il pourrait y avoir une énorme perte de précision/exactitude en faisant cela avec la gamme de valeurs qui m'intéresse. une idée approximative du genre d'erreur que je pourrais m'attendre en utilisant l'implémentation de Java? Je ne suis pas sûr de ce qui se passe sous le capot dans leur implémentation (logs et/ou approximations de Taylor?), Donc je ne peux pas hasarder une bonne estimation.Quelle est la précision/précision de java.lang.Math.pow (x, n) pour un grand n?

Je suis surtout préoccupé par l'erreur relative (c'est-à-dire que je ne sois pas éteint de plus d'un ordre de grandeur). Si la réponse s'avère être que l'implémentation de Java produira trop d'erreurs, avez-vous de bonnes recommandations de bibliothèque (mais encore une fois, j'espère que cela ne devrait pas être nécessaire)? Merci.

Répondre

4

According to the API doc:

Le résultat calculé doit être dans 1 ULP du résultat exact.

Donc, je ne pense pas que vous ayez besoin de vous soucier autant de l'implémentation que des limites de la précision en virgule flottante. Vous pouvez envisager d'utiliser BigDecimal.pow() si la précision plutôt que la performance est votre principale préoccupation.

+0

J'ai effectivement vérifié le Javadoc et pourtant j'ai raté cette ligne, merci. Quant à 'BigDecimal', je l'avais écarté avant de réaliser que' n' était un entier. Je pense que cela fonctionnerait aussi. –

0

Vous pouvez jeter un coup d'œil au fichier source de la classe java.land.Math et voir si vous pouvez comprendre la méthode exacte. Voici le lien, http://www.docjar.com/html/api/java/lang/Math.java.html.

+0

J'ai essayé cela, mais il a finalement recours au code natif et je ne savais pas où aller à partir de là. –

+0

Que diriez-vous d'essayer d'utiliser la classe Java StrictMath - http://download.oracle.com/javase/1.4.2/docs/api/java/lang/StrictMath.html. Je crois que les algorithmes sont beaucoup mieux définis dans la documentation (ou au moins nommez l'alg utilisé pour que vous puissiez le rechercher). – Zorayr

+0

@Michael McGowan L'implémentation du code natif java.lang.Math peut être trouvée à ftp://ftp.netlib.org/fdlibm.tar – Christopher

0

Quelques résultats empiriques:

public static void main(String[] args) 
{ 
    double e = 0.000000000001d; 
    System.out.println(Math.pow(1-e, 1.0d/e)); 
    float f = 0.000001f; 
    System.out.println(Math.pow(1-f, 1.0f/f)); 
} 

0.36788757938730976 
0.3630264891374932 

Les deux devraient converger vers 1/e (0,36787944 ....) si flotteur est évidemment hors de question, mais deux pourraient avoir assez de précision pour vous.

+2

Ceci ne mesure pas la précision de 'pow()'; c'est mesurer la précision de l'évaluation d'une expression contenant 'pow()' ainsi que la représentation en virgule flottante, la soustraction et la division. Même si 'pow()' était parfaitement précis, le résultat de ce calcul ne serait pas exactement égal à 1/e (et la valeur de cette expression ne passe pas à 1/e car l'argument passe à zéro lorsqu'on l'évalue en "idéal" arithmétique en virgule flottante). –

Questions connexes