Algorithme calcul Ln(x)
Résolu/Fermé
A voir également:
- Ln sur calculatrice ti-83
- Installer calculatrice sur mon portable - Télécharger - Calcul & Conversion
- Comment calculer la moyenne sur excel - Guide
- Calculatrice gratuit - Télécharger - Calcul & Conversion
- Supprimer programme ti 83 - Forum calculatrices
- Ln c++ ✓ - Forum C++
2 réponses
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 844
31 déc. 2015 à 13:49
31 déc. 2015 à 13:49
Bonjour,
Mes remarques sur ton code:
Attention à l'indentation qui n'est pas régulière
Le bon prototype de main() sans argument est : int main(void)
Pourquoi ne pas utiliser la constante M_E inclus dans math.h plutôt que recréer une variable e ?
for(i=0;i<11...) => Ca serait peut-être mieux de rendre paramétrable 11 par un #define par exemple.
Qu'entends-tu par améliorer l'algorithme ?
Si c'est "rendre plus performant", le mieux est probablement d'implémenter un autre algorithme.
Mes remarques sur ton code:
Attention à l'indentation qui n'est pas régulière
Le bon prototype de main() sans argument est : int main(void)
Pourquoi ne pas utiliser la constante M_E inclus dans math.h plutôt que recréer une variable e ?
for(i=0;i<11...) => Ca serait peut-être mieux de rendre paramétrable 11 par un #define par exemple.
Qu'entends-tu par améliorer l'algorithme ?
Si c'est "rendre plus performant", le mieux est probablement d'implémenter un autre algorithme.
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
31 déc. 2015 à 13:53
31 déc. 2015 à 13:53
Bonjour,
Je ne connais pas cet algorithme là mais puisque tu demandes de l'améliorer on va dire qu'il fonctionne déjà... Quelques remarques donc :
1) le choix des noms de variables est plutôt mauvais, quelqu'un qui lit ton programme ne peut pas savoir ce qu'elles font, x, y, p... ce n'est pas très explicite, alors quand en plus tu mélanges x et X, c'est galère !
2) e=2.7182818285, ceci est une approximation très... approximative.
Un double permet d'avoir 52 bits de précision, tu ne les utilises pas tous !
Pour un double tu devrais utiliser e=2.7182818284590452354
3) Pourquoi ta boucle for va de 0 à 11 ? Ça semble magique !
Idem, pourquoi faire la puissance de 0.1 ?
4) Ton résultat est un affichage, il pourrait être intéressant de faire une fonction qui prend un double en paramètre et renvoie un double en sortie.
5) Lors de l'affichage du résultat, il serait bien de montrer la différence entre le résultat obtenu avec ton calcul et le résultat obtenu avec la fonction de math.h
Je ne connais pas cet algorithme là mais puisque tu demandes de l'améliorer on va dire qu'il fonctionne déjà... Quelques remarques donc :
1) le choix des noms de variables est plutôt mauvais, quelqu'un qui lit ton programme ne peut pas savoir ce qu'elles font, x, y, p... ce n'est pas très explicite, alors quand en plus tu mélanges x et X, c'est galère !
2) e=2.7182818285, ceci est une approximation très... approximative.
Un double permet d'avoir 52 bits de précision, tu ne les utilises pas tous !
Pour un double tu devrais utiliser e=2.7182818284590452354
3) Pourquoi ta boucle for va de 0 à 11 ? Ça semble magique !
Idem, pourquoi faire la puissance de 0.1 ?
4) Ton résultat est un affichage, il pourrait être intéressant de faire une fonction qui prend un double en paramètre et renvoie un double en sortie.
5) Lors de l'affichage du résultat, il serait bien de montrer la différence entre le résultat obtenu avec ton calcul et le résultat obtenu avec la fonction de math.h
Salut
L'algorithme se base sur ça :
Tant que x>e on peut dire que :
Ln(x)=Ln(a*e^n) (Exemple : Ln(75)=Ln(1.37*e^4))
Tel que 1<a<e
Donc : Ln(x)=Ln(a)+4*Ln(e)=4+Ln(a)
Comme on a déjà le premier chiffre de Ln(75), c'est 4
On continue
Ln(a)=Ln(b*(e^0.1)^n1)=Ln(b)+n1*Ln(e^0.1)
Tel que
1<b<e^0.1
On sait que Ln(e^0.1)=0.1
Donc :
Ln(a)=Ln(b)+0.1*n1
Ln(x)=Ln(b)+n+0.1*n1
(Exemple : Ln(1.37)=Ln(1.02*(e^0.1)^0.3)=Ln(1.02)+0.3*Ln(e^0.1)=Ln(1.02)+0.3
Donc
Ln(75)=Ln(1.02)+4+0.3=Ln(1.02)+4.3)
On a la première décimale
Et on continue comme ça, à chaque fois en divisant sur 10 la puissance de e pour avoir plus de virgules
Le 11 c'est un paramètre de presicion, pour afficher 10 chiffres (9 après la virgule)
L'algorithme se base sur ça :
Tant que x>e on peut dire que :
Ln(x)=Ln(a*e^n) (Exemple : Ln(75)=Ln(1.37*e^4))
Tel que 1<a<e
Donc : Ln(x)=Ln(a)+4*Ln(e)=4+Ln(a)
Comme on a déjà le premier chiffre de Ln(75), c'est 4
On continue
Ln(a)=Ln(b*(e^0.1)^n1)=Ln(b)+n1*Ln(e^0.1)
Tel que
1<b<e^0.1
On sait que Ln(e^0.1)=0.1
Donc :
Ln(a)=Ln(b)+0.1*n1
Ln(x)=Ln(b)+n+0.1*n1
(Exemple : Ln(1.37)=Ln(1.02*(e^0.1)^0.3)=Ln(1.02)+0.3*Ln(e^0.1)=Ln(1.02)+0.3
Donc
Ln(75)=Ln(1.02)+4+0.3=Ln(1.02)+4.3)
On a la première décimale
Et on continue comme ça, à chaque fois en divisant sur 10 la puissance de e pour avoir plus de virgules
Le 11 c'est un paramètre de presicion, pour afficher 10 chiffres (9 après la virgule)
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
31 déc. 2015 à 17:21
31 déc. 2015 à 17:21
Outre mes premières remarques, je poursuis suite à tes explications.
Si je comprends bien ton
Or en informatique les nombres ne sont pas calculés en décimaux mais en binaire... et pourquoi s'arrêter à 10 chiffres après la virgule ?
Il serait peut-être plus pertinent de calculer
Ensuite je ne vois pas trop le rapport entre :
Ton calcul mathématique :
Et ton algorithme :
Mais cela revient sûrement au problème de nommage de tes variables...
Remarque au passage : y n'est jamais initialisée.
Si je comprends bien ton
for(i=0;i<11;i++) e=pow(e,0.1);cela consiste à calculer les dix premiers chiffres en décimal...
Or en informatique les nombres ne sont pas calculés en décimaux mais en binaire... et pourquoi s'arrêter à 10 chiffres après la virgule ?
Il serait peut-être plus pertinent de calculer
for(i=0;i<52;i++) e=sqrt(e);avec 52 le nombre de bits de précision d'un double et sqrt(e)==pow(e, 0.5)
Ensuite je ne vois pas trop le rapport entre :
Ton calcul mathématique :
Ln(x)=Ln(a*e^n) → Ln(x)=Ln(a)+n*Ln(e)
Et ton algorithme :
while(X>e) { X/=e; y+=p; }
Mais cela revient sûrement au problème de nommage de tes variables...
Remarque au passage : y n'est jamais initialisée.
Merci
Ça marche beaucoup mieux maintenant
A la base, j'ai voulu calculer les chiffres en décimaux pour contrôler le nombre de chiffres après la virgule qui pouvait être calculés
Mais c'est beaucoup mieux comme ça (il y a moins d'opérations finalement)
Juste que il y a une petite différence entre la fonction de math.h et celle ci, dans les deux dernères décimales pouvant être calculées
Ça marche beaucoup mieux maintenant
A la base, j'ai voulu calculer les chiffres en décimaux pour contrôler le nombre de chiffres après la virgule qui pouvait être calculés
Mais c'est beaucoup mieux comme ça (il y a moins d'opérations finalement)
#include <stdio.h> #include <stdlib.h> #include <math.h> #define precision 52 int main() { double e=M_E, x, C, ln=0, r=1; int i; do { printf("x = "); scanf("%lf", &x); } while(x<=0); if(x<1) C=1/x; else C=x; for(i=0;i<precision;i++) { while(C>e) { C/=e; ln+=r; } r/=2; e=sqrt(e); } if(x<1) ln*=-1; printf("Ln(%.6lf) = %.17lf\n", x, ln); printf("Ln(%.6lf) = %.17lf\n", x, log(x)); return 0; }
Juste que il y a une petite différence entre la fonction de math.h et celle ci, dans les deux dernères décimales pouvant être calculées
KX
Messages postés
16755
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 février 2025
3 020
31 déc. 2015 à 22:19
31 déc. 2015 à 22:19
La valeur de M_E c'est 2.71828182845905 qui n'a que 48 bits de précision.
Essayes avec 2.7182818284590452354 comme je l'indiquais précédemment, cela devrait résoudre ton problème de précision sur les dernières décimales.
Essayes avec 2.7182818284590452354 comme je l'indiquais précédemment, cela devrait résoudre ton problème de précision sur les dernières décimales.
31 déc. 2015 à 14:23
Oui justement je souhaiterais l'améliorer dans son écriture, pas dans ses performances (sans me vanter, il marche très bien)
J'ai aussi un peux de mal avec les virgules, le problème est que quand je tape un entier, ou un réel avec juste quelques virgules il m'affiche toujours toutes les virgules (genre 1.230000)