Petit souci de formule

Résolu
Bonjour a tous,

Voila c'est mon premier message sur se site que je trouve genial merci a tout ceux qui y participe
Bon bref je vous ecrit car j'ai un petit souci je doit ecrire un programme qui calcul log10(x) et log2(x) jusque la rien de terrible

Seulement c'est un projet de maths et donc bien entendu pas question d'utiliser les methodes standard présente dans tout les languages

voici une copie du sujet :
--------------------------------------------------------------------------------------------------------------------------------------------
x désigne un reel strictement positif
1) Montrer que x = M.10^y avec M € [1; 10 [ et y € Z

puis que M^10 = M1.10^y1 avec M1 € [1;10[ et y1 € {0,1,2, ..., 9}

Déduire des résultats precedents un algorithme de calcul de log10(x)

Ecrire un programme qui calcule log10(x) lorsqu'on lui donne x
-------------------------------------------------------------------------------------------------------------------------------------------

J'ai vraiment besoin d'aide au moins pour montrer la premiere equation apres je pense que je saurais adapter

Merci davance
Configuration: Windows XP
Firefox 2.0.0.6

30 réponses

Résumé de la discussion

Plusieurs échanges portent sur la démonstration x = M · 10^y avec M dans [1; 10[ et y dans Z, et sur un algorithme de calcul de log10(x) sans méthodes standard. Les discussions convergent vers log10(x) = y + log10(M), puis vers une expansion décimale où M^10 = M1 · 10^y1 et 0 ≤ log10(M1) < 1, afin d'obtenir les décimales progressivement. Plusieurs contributions proposent des implémentations en Java, et insistent sur le choix du nombre de décimales n, sur le traitement des cas x < 1 et x ≥ 1. En outre, certains messages évoquent le calcul de log2(x) par changement de base à partir de log10, et des variantes de code et vérifications numériques pour limiter les erreurs.

Bobot (l’IA à votre service)
  1. Voici un resumer de la solution comme j'avais promis de le faire

    Voici d'abort les deux fichier de demonstration
    Demo par ln
    Demo par log

    Ensuite l'inplémentation en mathLab (merci sacabouffe)
    function[res]=log10app(x,n)
    clear y; clear M; clear res;
    res=0; M=0;
    format long
    if (x<=0 || n<0)
        res='Erreur';
    else
        for k=0:n
            y=0;
            if k==0
                if x<1
                    while x/10^(y-1)<10
                        y=y-1;
                    end
                else
                    while x/10^y>=10
                        y=y+1;
                    end
                end
                M=x/10^y;
                res=y;
            else
                while M^10/10^y>=10
                    y=y+1;
                end
                M=M^10/10^y;
                res=res+y/10^k;
            end
        end
    end


    Et pour finir la traduction en Java
    import javax.swing.*;
    
    public class Log 
    {
         public static double log10X(long x, int n) throws Exception
         {
              // Utilisation du type double pour garder un maximum de precision lors du calcul
               double y;
               double M=0;
               double res=0;
    
               if (x<=0 || n<0)
               {
        	throw new Exception("La valeur de x est fausse !";
               }
              else
              {
                     for(int k=0; k<=n+1; k++) // Pour k decimal on calcul k+1 decimal pour plus de precision sur kieme decimal
                     {
                  	y=0;
                  	if (k==0)
                  	{
                       if (x<1)
                       {
                             while ((x/Math.pow(10.0, y-1))<10) // Math.pow calcul la puissance ici 10^y-1
                             {
                                  y=y-1;
                             } //fin while
                        } 
    	else
    	{
    	while ((x/Math.pow(10.0, y))>=10)
                        	{
                        	     y=y+1;
                        	} //fin while
                   } //fin if
                   
                  M=x/Math.pow(10.0, y);
                  res=y;
                  }
                  else
                  {
                  	while ((Math.pow(M, 10.0)/Math.pow(10.0, y))>=10)
                        {
                              y=y+1;
                         }// Fin while
    	
                        M=Math.pow(M, 10.0)/Math.pow(10.0, y);
                         res=(res+y/Math.pow(10.0, k));
                   }// Fin else
              }// Fin for
        } //fin else
        return res;
    } //fin methode
        
    
    //Petit bonus le calcul de log2X qui n'est autre qu'un reutilisation de log avec un changement de base
    public static double calculerLog2X(long x, int n) throws Exception
    {
        	String resTemp=log10X(x, n+1);
        	String resTemp1= log10X(2,n+1);
        	double res= logX/log2;
        	return res;
    }
        
        
    }
    


    Je tiens tout particulierement a remercier sacabouffe pour son aide et sa patience
    1. Bon j'ai changé un petit détail dans le code au lieu de m'arreter a k<=n je m'arrete a k<=n+1 car si on veux un resultat sur N decimal il nous faut calculer n+1 decimal pour que la nieme soit correcte et au moment de l'affichage on n'affiche le resultat que sur n decimal

      je metterrais au propre ma méthode et je la posterais
      En tout cas merci beaucoup pour ton aide
      1. oui dsl jai fait une erreur en tapant le nombre
        donc comme l'erreur est du a la machine donc aucun moyen de corriger cela a par tronquer le nombre au moment de l'affichage ?
        1. Je pense que le résultat que tu obtiens est plutôt 0.47700000...003 et vu où se trouve le 3 ça correspond vaisemblablement à l'erreur machine.
          1. Voila la methode en java qui marche super bien et en effet c'etait k<=net non k<n

            Par contre il y a une erreur sur un calcul que je ne comprend pas
            quand je fait log(3,3) le resultat est 0.47000000...003
            alors que pour les autres nombre sa marche nikel

            public static double log10X(int x, int n) throws Exception
            	{
            		int y;
                	double M=0;
                	double res=0;
            
                	if (x<=0 || n<0)
                		throw new Exception("Valeur fausse !");
                 	else
                	{
                 	     for(int k=0; k<=n; k++)
                    	 {
                          	y=0;
                          	if (k==0)
                          	{
                               if (x<1)
                               {
                                     while ((x/Math.pow(10.0, y-1))<10)
                                     {
                                          y=y-1;
                                     } //fin while
                                } // fin if
            					else
            					{
            						while ((x/Math.pow(10.0, y))>=10)
                                	{
                                	     y=y+1;
                                	} //fin while
                           		} //fin if
                           
                          		M=x/Math.pow(10.0, y);
                          		res=y;
                          	}
                          	else
                          	{
                          		while ((Math.pow(M, 10.0)/Math.pow(10.0, y))>=10)
                                {
                                      y=y+1;
                                 }// Fin while
            	
                            	     M=Math.pow(M, 10.0)/Math.pow(10.0, y);
                        	         res=res+y/Math.pow(10.0, k);
                    	       }// Fin else
                    	  }// Fin for
                	} //fin else
                	System.out.println(res+"");
                	return res;
            	} //fin methode
            1. Il y a pas besoin de déclaration de type ou de dimension avec Matlab, c'est implicite.
              En fait clear c'était pour tout effacer au cas où les variables auraient été utilisés avant.
              C'est au moment où on met ces variables à 0 que Matlab leur donne un type.

              format long c'était pour régler l'affichage des nombres avec plus de décimales que le mode par défaut (qui doit être de 4).

              y est initialisé juste après l'entrée dans la boucle.

              Et une question : tu as mis k<n dans ton code, est-ce normal? Je dirais plutôt k<=n.

              Et sinon, ça marche?
              Moi c'est nickel...
              PS : si tu connais un moyen de compter les chiffres qui composent un nombre en java, ce serait plus simple pour calculer y
              PPS : c'est pas un algorithme qui prend 3 jours de calcul mais peut-être qu'en exploitant le fait que log10(x) = - log10(1/x) ça permet de simplifier un peu le programme et de gagner quelques microsecondes en ne considérant que le cas x>=1 et en ajoutant un moins pour x<1
              1. Petit essai de traduction en java

                public static double log10X(int x, int n) throws Exception
                {
                     int y;
                     double M=0;
                     double res=0;
                
                     if (x<=0 || n<0)  
                          throw new Exception("Valeur fausse !");
                     else
                     {
                          for(int k=0; k<n; k++)
                          {
                              y=0;
                              if (k==0)
                              {
                                   if (x<1)
                                   {
                                         while (x/10^(y-1)<10)
                                         {
                                              y=y-1;
                                          } //fin while
                                    } // fin if
                
                                    while (x/10^y>=10)
                                    {
                                         y=y+1;
                                     } //fin while
                               } //fin if
                               
                              M=x/10^y;
                              res=y;
                              
                              else
                              {
                                    while (M^10/10^y>=10)
                                    {
                                          y=y+1;
                                     }// Fin while
                
                                     M=M^10/10^y;
                                     res=res+y/10^k;
                               }// Fin else
                          }// Fin for
                    } //fin else
                } //fin methode
                --
                 La franchise ne consiste pas à dire tout ce que l'on pense, mais à penser tout ce que l'on dit.
                1. Non c'est plus en java que je dois rédiger cette fonction
                  Par contre je ne connais pas du tout le language MathLab donc je vais te dire ce que je comprend au code et tu n'auras qu'a me dire si je fais une erreur
                  // Declaration de la fonction qui prend en paramettre X (valeur) et N (nombre de decimal)
                  function[res]=log10app(x,n) 


                  // Declaration des variables de la fonction
                  clear y; clear M; clear res; 


                  // Initialisation de leur valeur
                  res=0; M=0; 


                  // Connais pas du tout
                  format long  


                  // Test verifiant la validité des donnees transmise
                  if (x<=0 || n<0)  

                     res='Erreur';
                  else


                  // Repete tant que K n'est pas égale a N
                     for k=0:n  
                          y=0;
                          if k==0
                              if x<1

                  // La je ne vois pas ou est initialisé Y mais je comprend l'algo
                                  while x/10^(y-1)<10
                                      y=y-1;
                                  end
                              else
                                  while x/10^y>=10
                                      y=y+1;
                                  end
                              end
                              M=x/10^y;
                              res=y;
                          else
                              while M^10/10^y>=10
                                  y=y+1;
                              end
                              M=M^10/10^y;
                              res=res+y/10^k;
                          end
                      end
                  end


                  Je supose qu'en MathLab la variable RES est retourné automatiquement a la fin de la methode
                  1. C'est en C que tu le fais?
                    J'ai un peu oublié ce langage depuis le temps...
                    En Matlab ça donnerait un truc comme ça:
                    function[res]=log10app(x,n)
                    clear y; clear M; clear res;
                    res=0; M=0;
                    format long
                    if (x<=0 || n<0)
                        res='Erreur';
                    else
                        for k=0:n
                            y=0;
                            if k==0
                                if x<1
                                    while x/10^(y-1)<10
                                        y=y-1;
                                    end
                                else
                                    while x/10^y>=10
                                        y=y+1;
                                    end
                                end
                                M=x/10^y;
                                res=y;
                            else
                                while M^10/10^y>=10
                                    y=y+1;
                                end
                                M=M^10/10^y;
                                res=res+y/10^k;
                            end
                        end
                    end
                    

                    Et pis après il y a la possibilité d'améliorer pour comparer le résultat avec la fonction log10 de Matlab, etc...

                    Il se peut que l'appellation "nieme décimale" pour l'arrêt de la boucle soit pas apprécié vu que c'est pas vraiment la "nieme décimale" quand x<1. Tu peux éventuellement dire "approximation à 10^(-n) près", ce sera peut-être mieux...
                    1. D'accord je comprend a peu pres pour determiner les variable
                      et pour ce qui est ce la programmation je devrai pouvoir faire un truc du genre

                      public static nDecimalCourante;

                      public static float log10X(int x, int nDecimalSouhaite)
                      {
                                   // definition des variable
                                  // Calcul du premier log
                                 // incrementation de nDecimal
                                // test de nDecimalCourante Si nDecimalSouhaite!=nDecimalCourante on rappel log
                      }

                      1. Euh ben non, en si je t'ai dit de pas oublier que log10 = ln/ln(10) dans le mesage 12 c'était parce que ta formule log10(x) = (ln M + ln 10^y) / ln 10 de ton message 11 se simplifiait en log10(x) = y + log10(M).

                        Pour ton algorithme je pense que tu dois te fixer un nombre de décimales au début (appelons le n) et tu fais une boucle jusqu'à ce que t'atteignes n en incrémentant à chaque boucle la valeur du log10 calculé:
                        premier passage : log10 = y
                        deuxième passage log10 = log10 + y1/10
                        troisième passage log10 = log10 +y2/100
                        etc...
                        et au final log10 = y + y1/10 + ..... + yn/10^n

                        Pour déterminer le M et le y il y a que la première fois que c'est un peu chiant.
                        En fait c'est facile de vérifier que y= inf { p ; x/10^p < 10 } (d'ailleurs si tu veux faire comme ça pour les 2 premières questions ça reste possible et ça te permet de faire le lien avec ton algorithme).

                        Pour le tout premier passage dans la boucle le mieux c'est de séparer le cas où x < 1 et le cas où x >= 1.

                        Si x < 1, tu pars de y=-1 et tu diminues alors y jusqu'à ce que x/10^y >= 10 et le bon y c'est celui qui vaut celui que tu viens de tester +1.

                        Si x >= 1, la première valeur de y (en partant de 0 et en augmentant) telle que x/10^y < 10 est la bonne.

                        Pour les boucles suivantes pas besoin de faire de disjonction de cas puisque tu as tout le temps Mn^10 > = 1. Tu pars de 0 et tu augmentes.

                        Voilà et je me permets d'apporter une toute petite modification à ce que j'ai dit au message 12:
                        ""Du coup tu vois que pour tout n, yn est la nième décimale de log10(x)""
                        En fait c'est vrai si x >= 1, sinon c'est pas tout à fait ça...
                        1. donc au niveau programmation soit je fait une fonction recursive soit jutilise le logarithme népérien c'est sa ? j'ai bien compris ?
                          et une autre question comment déterminé M et y ? je teste toute les solution ?
                          1. En remplaçant log10(M) = y1/10 + log10(M1)/10 dans la ligne log10(x) = y + log10(M).
                            1. Pour le fichier je viens de le parcourir et je pense avoir compris par contre je ne comprend pas comment tu passe de cette ligne
                              C'est-à-dire log10(M) = y1/10 + log10(M1)/10 avec 0 =< log10(M1)/10 < 1/10
                              a celle ci
                              Et donc log10(x) = y + y1/10 + log10(M1)/10 avec 0 =< log10(M1)/10 < 1/10
                              1. je te remercie pour ta reponse je vais prendre le temps de bien regarder et de comprendre toutes tes explications et je te dirais si j'ai tout compris
                                en tout cas merci pour ta patience
                                1. Salut Lefleau02

                                  Là tout à coup je me rend compte que j'ai été un peu stupide de travailler avec le logarithme népérien pour ton problème. C'était carrément plus naturel avec le logarithme en base 10, plus simple et en plus t'aurais surement mieux vu d'où allait bien pouvoir venir ton algorithme.
                                  Du coup prends plutôt ce fichier.

                                  Pour ton algorithme, l'égalité que tu as écrite est juste (au passage oublie pas que log10 = ln/ln(10)) et je pense que c'est bien comme ça qu'il faut partir.
                                  Tu as log10(x) = y + log10(M) avec 0 =< log10(M) < 1
                                  Ensuite 10 log10(M) = y1 + log10(M1) avec 0 =< log10(M1) < 1
                                  C'est-à-dire log10(M) = y1/10 + log10(M1)/10 avec 0 =< log10(M1)/10 < 1/10
                                  Et donc log10(x) = y + y1/10 + log10(M1)/10 avec 0 =< log10(M1)/10 < 1/10

                                  Et tu itères le procédé M1^10=M2.10^y2 avec 1 =< M2 < 10 et y2 € {0,1,2, ..., 9} .
                                  Dans ce cas tu as log10(x) = y + y1/10 + y2/100 + log10(M2)/100 avec 0 =< log10(M2)/100 < 1/100.
                                  Bis repetita...
                                  Du coup tu vois que pour tout n, yn est la nième décimale de log10(x) car
                                  log10(x) = y + y1/10 + ......... + yn/10^n + log10(Mn)/10^n avec 0 =< log10(Mn)/10^n < 1/10^n

                                  Voilà...
                                  Et tu arrêtes ton algorithme à la décimale que tu veux. C'est bon? Tu veux que je détailles un peu plus?
                                  1. Décidément j'ai encore une petite question
                                    le but initial de cette démonstration était de dégager un algorithme pour la calcul de log10(x)
                                    Donc la démonstration je l'ai comprise sa il n'y a pas de souci seulement je me retrouve bloqué par les deux inconnu M et y
                                    si je fait apparaitre log10(x) sa donne sa

                                    log10(x) = (ln M + ln 10^y) / ln 10

                                    alors est ce que je part pas du tout de la bonne formule ? est ce que j'ai fait une erreur ?
                                    • 1
                                    • 2