Cet article a un prédécesseur et un successeur.
La question
Bonjour, j’ai écrit une classe de calcul de nombres de Fibonacci :
que j’appelle ainsi :
Tout marche bien, sauf pour num === 0 ou pour num === 1, où la méthode fib_iter est invoquée, alors qu’elle ne devrait pas. Pourquoi appelle-t-on fib_iter dans ce cas, qui provoque une erreur “RangeError : Maximum call stack size exceeded” ?
Réponse 1
Excellente question, Laurent — ton code est très proche du but, et l’erreur vient d’un petit piège classique lié au typage de Commander et à la conversion des arguments.
Regardons pas à pas :
Le problème réel : num n’est pas un number
Quand tu écris :
tu crois que Commander va passer un nombre… mais en réalité Commander passe toujours des chaînes de caractères (string), sauf si tu fais explicitement la conversion.
Donc quand tu tapes, par exemple :
./fibonacci 1
la fonction reçoit en réalité num = "1" (une chaîne).
Et en TypeScript, le test suivant :
if (num === 0 || num === 1)
échoue, car "1" === 1 est faux.
Donc tu passes dans le else, qui appelle fib_iter, d’où la récursion infinie et ton erreur :
RangeError : Maximum call stack size exceed
La correction : convertir num en nombre
Il suffit de faire une conversion explicite au moment de l’appel :
ou directement dans la fonction :
Petite remarque sur ta méthode fib_iter
Ta méthode renvoie bien a quand compteur === 1, mais elle ne retourne rien dans le cas récursif.
Ce n’est pas bloquant ici (puisque tu affiches le résultat), mais pour avoir une vraie fonction de calcul, tu devrais retourner le résultat de l’appel récursif :
Version corrigée complète
Souhaites-tu que je t’écrive aussi une version itérative (non récursive) de fib_iter, pour comparaison de performance et de style ?
Version itérative
Voici donc une version itérative (non récursive) de ta classe Fib, parfaitement équivalente sur le plan du résultat, mais sans appel récursif.
Elle est généralement plus efficace (pas de coût d’appels de pile) et plus sûre (pas de risque de RangeError).
Explication
La boucle for fait exactement ce que ta récursion faisait :
– à chaque itération, on calcule la nouvelle paire (a, b) ;
– a devient a + b, et b devient l’ancien a ;
– on répète cela compteur - 1 fois.
À la fin, a contient la valeur du nombre de Fibonacci d’indice compteur.
Programme principal (inchangé) :
ChatGPT est vraiment un de mes meilleurs amis !
Cet article a un prédécesseur et un successeur.