Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1541 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  Puisssance d'un nombre(fonction récursive)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Puisssance d'un nombre(fonction récursive)

n°2343632
Nat1329
Posté le 26-12-2019 à 14:56:54  profilanswer
 

Bonjour,
 
Je voudrais ecrire une fonction qui fait la puissance d'un nombre jusqu'à que ce nombre soit egale a une valeur a tester.
 
Par exemple,  
valeur a tester = 1455
Nombre = 3
 
Le programme doit faire 3×3×3...×3 jusqu'à que le result soit superieure ou egale a 1455.
 
Avez vous une idée ?  
 
Je sais faire pour la puissance d'un nombre avec l'exposant deja connu a l'avance ca donne ceci  mais pour mon exemple a faire je bloque.
 

Code :
  1. public int puiss(int n, int k)
  2. {
  3. int result;
  4. if (k == 0)
  5. return 1;
  6. else
  7. return  (n * puiss(n,k-1)) ;
  8. }


   

mood
Publicité
Posté le 26-12-2019 à 14:56:54  profilanswer
 

n°2343634
MaybeEijOr​Not
but someone at least
Posté le 26-12-2019 à 15:30:59  profilanswer
 

Bonjour,
 
Il te suffit de partir de l'exposant 0 et de l'augmenter à chaque nouvel appel de la fonction au lieu de le diminuer. Faut aussi changer la condition dans ta fonction pour qu'elle corresponde à supérieur ou égale à ton nombre limite.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2343705
rufo
Pas me confondre avec Lycos!
Posté le 29-12-2019 à 13:31:47  profilanswer
 

La récursivité, c'est une obligation ? Parce que c'est pas le plus optimisé. Même avec des petits nombres, tu arriveras vite à faire péter la pile d'appels et de sauvegarde du contexte. :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
n°2343902
Lt Ripley
Ils ont tout niqué
Posté le 03-01-2020 à 19:10:25  profilanswer
 

Salut
 
J'ai fait une méthode non récursive et une récursive.  Mais je ne sais pas pourquoi celle récursive donne le résultat plusieurs fois [:cerveau ddr555]  
 

Code :
  1. public static void moulinette(int base, double result) {
  2.  
  3.        double temp = 0;
  4.        int exposant = 1;
  5.  
  6.        while (temp<result) {
  7.  
  8.            temp = Math.pow(base, exposant);
  9.  
  10.            if (temp != result) {
  11.                exposant++;
  12.            }
  13.  
  14.        }
  15.  
  16.        if (temp == result) {
  17.            System.out.println("Succes : Base : " + base + "  Resultat : " + temp + "  Exposant : " + exposant);
  18.        }
  19.        else { System.out.println("Pas de correspondance" );}
  20.  
  21.    }


 
 

Code :
  1. public static void moulinetteRec(int base, double result, int exposant) {
  2.  
  3.        double temp = 0;
  4.  
  5.        while (temp<result) {
  6.  
  7.            temp = Math.pow(base, exposant);
  8.  
  9.            if (temp < result) {
  10.                exposant++;
  11.                moulinetteRec(base, result, exposant);
  12.            }
  13.  
  14.        }
  15.  
  16.        if (temp == result) {
  17.            System.out.println("Succes : Base : " + base + "  Resultat : " + temp + "  Exposant : " + exposant);
  18.        }
  19.        else { System.out.println("Pas de correspondance" );}
  20.  
  21.    }


---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2343906
MaybeEijOr​Not
but someone at least
Posté le 03-01-2020 à 20:53:52  profilanswer
 

Dans ta fonction récursive il faut virer le while (même s'il ne fait qu'un tour en fin de compte, il n'a pas de sens).
En fait tu as deux cas (à ce moment là tu sais que tu faire un IF ... ELSE ...), soit ton résultat de calcule est inférieur à celui demandé et donc tu rappelles ta fonction en incrémentant l'exposant, soit ton résultat est supérieur ou égale à celui demandé, auquel cas tu affiches la valeur atteinte de l'exposant.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
n°2343931
Lt Ripley
Ils ont tout niqué
Posté le 04-01-2020 à 18:04:56  profilanswer
 

Merci, j'ai viré le while, et j'ai le résultat une seule fois maintenant, niquel [:cerveau d]
 
Edit : c'est vrai aussi que dans l'énoncé du posteur il faut afficher le résultat dès qu'on atteint la valeur testée, qu'on soit égal ou supérieur
 
 

Code :
  1. private static void moulinette(int base, double resultat) {
  2.  
  3.        double temp = 0;
  4.        int exposant = 1;
  5.  
  6.        while (temp < resultat) {
  7.  
  8.            temp = Math.pow(base, exposant);
  9.  
  10.            if (temp < resultat) {
  11.                exposant++;
  12.            }
  13.        }
  14.        System.out.println("Base = " + base + "  Resultat (supp ou egal a " + resultat + " ) = " + temp + "  Exposant = " + exposant);
  15.    }
  16.  
  17.  
  18.  
  19.  
  20.    private static void moulinetteRec(int base, double resultat, int exposant) {
  21.  
  22.        double temp = 0;
  23.  
  24.        temp = Math.pow(base, exposant);
  25.  
  26.        if (temp < resultat) {
  27.            exposant++;
  28.            moulinetteRec(base, resultat, exposant);
  29.        }
  30.  
  31.  
  32.        else {
  33.            System.out.println("Base = " + base + "  Resultat (supp ou egal a " + resultat +" ) = " + temp + "  Exposant = " + exposant);
  34.        }
  35.    }


Message édité par Lt Ripley le 04-01-2020 à 19:30:51

---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344272
mathieuu
Posté le 09-01-2020 à 15:48:28  profilanswer
 

Salut,
 
Niveau perf, cela ne me semble pas super judicieux de recalculer à chaque fois la nouvelle valeur avec avec pow :-/  
 
Je ne sais pas comment c'est codé pow, mais si c'est une fonction "con", chaque tour de récursion reviennent à faire en gros :  
3*3
3*3=9 puis 9*3=27
3*3=9 puis 9*3= 27 puis 27*3= 81
 
Si on cherche un grand nombre, je pense que c'est rapidement pas terrible comme solution :-/
 
alors qu'en gardant en mémoire le précédent résultat, on doit pouvoir se contenter de faire à chaque tour de récursion :  
3*3 =9
9*3 = 27
27*3 = 81
81*3 = 243
243*3=729
729*3=2187
 
 
 
Après si on cherche à faire encore des économies sur le nombre de calcul à faire, on doit pouvoir essayer de s'inspirer de la recherche dichotomique pour s'approcher plus vite de la valeur  mais ça va compliqué l'algo (et pas être super intéressant dans pour des valeurs assez basses)  
Exemple :  
3*3=9
9*9=81 (on économise le calcul de 3*9)
81*81= 6561 (on économise le calcul de 243, 729 , 2187 mais au final on est trop haut et on est obligé de vérifié l'intervalle (en recherche dichotomique on le coupe en 2 donc on calcul 729 qui est trop bas puis on calcul 2187 qui est la bonne solution, dans ce cas la on a juste économisé le calcul de 243 mais on y a perdu a faire le calcul de 6561 par rapport a l'algo précédent donc c'est kifkif, mais pour des plus grandes valeurs ça doit être rapidement rentable je pense :-)

n°2344385
Lt Ripley
Ils ont tout niqué
Posté le 11-01-2020 à 15:29:01  profilanswer
 

J'ai fait une methode comme tu le dis (moulinetteMod).
 
Et j'ai implémenté un "contrôle" du temps, mais je ne sais pas si je l'ai fait correctement car j'ai eu ces valeurs hier :
 
moulinette : 2 998 300
 
moulinetteMod : 2 010 400
 
Puis aujourd'hui :
 
moulinette : 1 001 300
 
moulinetteMod : 1 000 500 et aussi un truc dans les 2 000 000
 
Et mon contrôle du temps ne fonctionne pas avec moulinetteRec la méthode récursive, je pense qu'il me faut des variables globales à ce niveau
 

Code :
  1. private static void moulinetteMod (int base, double resultat) {
  2.  
  3.        LocalDateTime first = LocalDateTime.now();
  4.        double temp = base;
  5.        int exposant = 1;
  6.  
  7.        while (temp < resultat) {
  8.  
  9.            temp = temp*base;
  10.  
  11.            exposant++;
  12.        }
  13.  
  14.        LocalDateTime second = LocalDateTime.now();
  15.        long diff = ChronoUnit.NANOS.between(first, second);
  16.  
  17.        System.out.println("Base = " + base + "  Resultat (supp ou egal a " + resultat + " ) = " + temp + "  Exposant = " + exposant + "  Temps execution programme = " + diff);
  18.    }


Message édité par Lt Ripley le 11-01-2020 à 15:29:37

---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344834
mathieuu
Posté le 20-01-2020 à 17:58:49  profilanswer
 

Pour les calculs de durée tu devrais sortir le code qui calcul la durée du code qui appelle la fonction de calcul du resultat.
 
En mini solution récursive en javascript parce que plus simple pour moi de faire ça dans le navigateur même si c'est pas vraiment adapté au sous forum java... c'est juste pour montrer le principe de la récursion :  
 

Code :
  1. function puissance(nb, nb_a_depasser, nb_actuel=1){
  2.     if(nb<=1){
  3.      console.log("merci de saisir un nombre superieur à 1 pour que la valeur augmente" );
  4.  return 0;
  5.     }
  6. nb_actuel=nb*nb_actuel;
  7. console.log("nb :"+nb+" nb a depasser : "+ nb_a_depasser+" nb_actuel : "+nb_actuel);
  8.     if(nb_a_depasser<=nb_actuel)
  9.     {
  10.      return 1; //on a trouver , on arrete la
  11.     }
  12. else{
  13.  return 1+ puissance(nb, nb_a_depasser, nb_actuel);
  14.     }
  15. }


 
Cela retourne l'indice qui va bien en faisant une seule multiplication par récursion. Faudra que je vois pour de la recherche dichotomique mais je pense que ca risque de compliquer :-/


Message édité par mathieuu le 21-01-2020 à 07:49:47
n°2344837
Lt Ripley
Ils ont tout niqué
Posté le 20-01-2020 à 18:36:29  profilanswer
 

En plus chui con, ma moulinetteMod elle n'est pas récursive [:zzozo]


---------------
Mes apps  |  Viens coder  |  Mon topal de vente
mood
Publicité
Posté le 20-01-2020 à 18:36:29  profilanswer
 

n°2344844
Lt Ripley
Ils ont tout niqué
Posté le 20-01-2020 à 20:15:37  profilanswer
 

Voilà ma dernière méthode, récursive.
 
J'ai sorti le calcul du temps pour toutes mes méthodes. (je prends l'heure, j'appelle ma methode, je reprends l'heure et je fais la différence). J'ai toujours des différences (+50%) d'un lancement à un autre pour une même méthode avec les mêmes nombres entrés.
 

Code :
  1. private static void moulinetteModRec (int base, double aAtteindre, double temp, int exposant) {  //lors du premier appel temp = base et exposant = 2
  2.  
  3.        temp=temp*base;
  4.  
  5.        if(temp < aAtteindre) {
  6.  
  7.            exposant++;  // ne sert que pour l'indiquer quand on a atteint le nombre
  8.            moulinetteModRec(base, aAtteindre, temp, exposant);
  9.        }
  10.  
  11.        else {
  12.            System.out.println("Base = " + base + "  Résultat (supp ou egal a " + aAtteindre + " ) = " + temp + "  Exposant = " + exposant );
  13.        }
  14.    }


 
La console :  
https://i.imgur.com/TXQpuXg.png


Message édité par Lt Ripley le 20-01-2020 à 20:28:44

---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344851
Lt Ripley
Ils ont tout niqué
Posté le 21-01-2020 à 00:10:26  profilanswer
 

Je suis en train de tester, avec une boucle for je viens de lancer 1 million de fois chaque méthode, séparément, ça met 3 secondes a se faire environ, c'est pas assez, les scores sont trop proches pour départager !  Demain je lance des boucles de 10 ou 20 millions de fois


---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344852
mathieuu
Posté le 21-01-2020 à 07:56:42  profilanswer
 

Plutôt que d'augmenter le nombre de boucle il faudrait augmenter le nombre à atteindre, la il arrive très vite à 500 : 2, 4, 8, 16, 32, 64, 128, 256, 512  
Il faudrait plutôt atteindre des millions voire des milliards pour que l'on puisse finir par voir une différence minime je pense

n°2344865
Lt Ripley
Ils ont tout niqué
Posté le 21-01-2020 à 11:27:12  profilanswer
 

Oui j'avais déjà augmenté à 5 millions j'ai oublié de dire.  Je viens de mettre 999 millions (j'arrive pas à mettre plus même avec un type long) mais c'est atteint très rapidement tout de même j'avais fait l'essai (500 millions = exposant 29 seulement)
 
Donc : base 2,  nombre a atteindre 999 999 999,  10 millions de boucles
 
 
Résultats de 2 essais par méthode, en secondes :
 
Méthode pow non récursive
28
28,2
 
Méthode pow récursive
30
30,7
 
Méthode base*base non récursive
26
26,5
 
Méthode base*base récursive
26
26,7
 
Je crois donc que tu avais bien raison, pow coute plus que de multiplier simplement


Message édité par Lt Ripley le 21-01-2020 à 12:51:19

---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344868
mathieuu
Posté le 21-01-2020 à 11:56:38  profilanswer
 

Oui la fonction puissance augmente très rapidement en valeur du coup on atteint très rapidement le nombre à atteindre.  
 
Il faudra que je prenne le temps de regarder dans chrome, il me semble qu'on peut aller beaucoup plus haut en valeur (2^999 ?) avant que cela considère que c'est une valeur infini.
 
Hop mini edit pour la fonction recursive avec un timer a mettre dans la console javascript (f12 sur firefox ou chrome)
 

Code :
  1. function puissance_recursive(nb, nb_a_depasser, nb_actuel=1){
  2.     if(nb<=1){
  3.      //console.log("merci de saisir un nombre superieur à 1 pour que la valeur augmente" );
  4.  return 0;
  5.     }
  6. nb_actuel=nb*nb_actuel;
  7. //console.log("nb :"+nb+" nb a depasser : "+ nb_a_depasser+" nb_actuel : "+nb_actuel);
  8.     if(nb_a_depasser<nb_actuel)
  9.     {
  10.         return 1; //on a trouver , on arrete la
  11.     }
  12. else{
  13.  return 1+ puissance_recursive(nb, nb_a_depasser, nb_actuel);
  14.     }
  15. }
  16. console.time("Puissance_recursive" );
  17. console.log(puissance_recursive( 2 ,999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
  18. console.timeEnd("Puissance_recursive" );


 


Message édité par mathieuu le 21-01-2020 à 12:08:11
n°2344872
Lt Ripley
Ils ont tout niqué
Posté le 21-01-2020 à 13:01:00  profilanswer
 

Ça me sort ça
 
https://i.imgur.com/nldFMOf.png
 
Mais j'ai eu une fois 1ms et une fois 2ms
 
997 c'est l'exposant ?
 
Faut que je regarde comment dépasser 999 999 999 en JAVA


Message édité par Lt Ripley le 21-01-2020 à 13:01:21

---------------
Mes apps  |  Viens coder  |  Mon topal de vente
n°2344879
mathieuu
Posté le 21-01-2020 à 13:50:23  profilanswer
 

Oui c'est l'exposant obtenu (et donc le nombre de fois que la fonction s'appelle à elle même en gros)  
 
J'ai aussi vite fait réadapté pour passer l'exposant et recalculer avec pow :  
 

Code :
  1. function puissance_recursive_pow(nb, nb_a_depasser,exposant=1){
  2. temp=Math.pow(nb,exposant);
  3. if(temp< nb_a_depasser){
  4.  exposant++;
  5.  return 1+puissance_recursive_pow(nb,nb_a_depasser,exposant);
  6.     }
  7. else{
  8. return 1;
  9.     }
  10. }
  11. console.time("Puissance_recursive_pow" );
  12. console.log(puissance_recursive_pow( 2 ,999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
  13. console.timeEnd("Puissance_recursive_pow" );

n°2344882
mathieuu
Posté le 21-01-2020 à 14:06:54  profilanswer
 

Et mini bout de code pour comparer les appels aux 2 fonctions de 2 jusqu’à 10m :  
 

Code :
  1. console.time("Puissance_recursive" );
  2. for(i=2;i<10000000;i++){
  3. console.log(puissance_recursive( i ,999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
  4. }
  5. console.timeEnd("Puissance_recursive" );
  6. console.time("Puissance_recursive_pow" );
  7. for(i=2;i<10000000;i++){
  8. console.log(puissance_recursive_pow( i ,999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999));
  9. }
  10. console.timeEnd("Puissance_recursive_pow" );


 
J'obtiens :  
Puissance_recursive: 4686.41796875ms
Puissance_recursive_pow: 16878.303955078125ms
 
Soit environ 4 fois mieux en passant le résultat de la multiplication a chaque itération plutôt qu'en passant l'exposant et en recalculant la multiplication (et je m'attendais à mieux xD)
 
Au départ j'ai mis la boucle jusqu'à 1milliard mais c'est trop long j'ai eu la flemme d'attendre donc j'ai diminué ^^
 
Edit : avec 100million :  
Puissance_recursive: 42656.34716796875ms
Puissance_recursive_pow: 148851.09619140625ms
Encore un peu moins de 4 fois mieux


Message édité par mathieuu le 21-01-2020 à 14:10:22
n°2345441
Lt Ripley
Ils ont tout niqué
Posté le 30-01-2020 à 10:15:26  profilanswer
 

Bon, j'ai amélioré mon code, à savoir que j'affichais 10 millions de fois le résultat dans la console puisque l'affichage se faisait dans mes méthodes.  J'ai donc sorti l'affichage et il ne se fait plus qu'une seule fois à la fin.
 
Ça n'a plus rien à voir, le prog est bien plus rapide et les méthodes base*base sont 3x plus rapides qu'avec pow tu as raison
 
pow : 15,3sec
pow recursive : 16,5sec
base*base : 5,1sec
base*base recursive : 5,5sec
 
Edit :
Nombre à atteindre : 8 999 999 999 999 999 999
base : 2
10 millions de boucles


Message édité par Lt Ripley le 30-01-2020 à 10:25:52

---------------
Mes apps  |  Viens coder  |  Mon topal de vente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  Puisssance d'un nombre(fonction récursive)

 

Sujets relatifs
Fonction mail() de PHP avec plusieurs serveurs SMTPExcel VBA : fonction indiquant #value au démarrage
[MySQL] Ajouter un nombre à une colonne null[Python] Exercice nombre premiers et fonction seuil
Afficher / masquer div en fonction d'une liste déroulante (jQuery/JS)[RESOLU] petite aide appel fonction powershell
[MySQL] Nombre de cours et exercices avec une seules requête[résolu] Figer la valeur paramètre quand passé à une fonction
[AIDE] Highcharts - graphique en fonction d'une var ID et Time 
Plus de sujets relatifs à : Puisssance d'un nombre(fonction récursive)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR