CALCUL DE LA FACTORIELLE D'UN NOMBRE N

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 24 nov. 2003 à 22:57
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 - 2 juin 2004 à 19:42
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/18191-calcul-de-la-factorielle-d-un-nombre-n

garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
2 juin 2004 à 19:42
cyril21 : la formule est correcte mais ça reste une approximation et surtout la complexité est bien supérieure à celle de cette fonction! Sais-tu comment un ordi calcule une racine carrée ?... si ça t'interesse regarde dans mes sources : "Math.h reprogrammé"

La complexité informatique ne se mesure pas au nombre de lignes ...
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
2 juin 2004 à 13:32
Oui je crois que c'est la formule de Stirling :
n _______
n! ~ (n/e) * \/ 2.pi.n

ceci est une approximation du meme ordre de grandeur que n!.
cs_cyril21 Messages postés 1 Date d'inscription mardi 1 juillet 2003 Statut Membre Dernière intervention 2 juin 2004
2 juin 2004 à 12:18
Pour des factorielles supérieurs à 20, j'utilise la formule suivante dont la précision me semble correcte et qui est beaucoup plus rapide car une seule ligne.
x! = Sqr(2 * x * Pi) * (x / E) ^ x
avec Const Pi 3.14159265358979, E2,71828182845905 (correspond à exp(1))
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
25 nov. 2003 à 18:24
je ne suis pas d'accord avec toi JCDjcd.
Car ces pb interviennent pour les très grands nombres. On n'y cherche pas forcément la précision. D'autant plus que les factorielles élevées sont des multiples de puissances de 10, donc ce sont les premiers chiffres qui comptent finalement.
cs_JCDjcd Messages postés 1138 Date d'inscription mardi 10 juin 2003 Statut Membre Dernière intervention 25 janvier 2009 4
25 nov. 2003 à 17:23
Cette fonction m'est familiere, j'en est deja fais une ... mais bon.

C'est pas genant d'avoir des double des des int, ily a des probleme de cast. Ici le double n'est pas justifier, car meme s'il peut aller jusqu'a des nomre a exposant, il n'a pas une nombre infini de decimal.
Donc le mieux est de faire un unsigned __int64
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
25 nov. 2003 à 10:40
ben simple:
si tu as:
void MaFunc(DWORD v);
void MaFunc(BYTE v);
Dans les 2 cas le compilo poussera un DWORD sur la pile mais jamais 8 bits seulement sinon le registre ESP qui controle la stack ne serait plus aligne sur 4.
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
25 nov. 2003 à 10:31
Mais euh...
Tu ne crois pas que la notion de beauté s'applique à la programmation ? Moi je trouve que c'est important l'élégance d'une solution. (entre autres pour la lisibilité et la réutilisabilité du code)

Je n'ai pas bien compris ta remarque "Note qu'un compilo pour 32 bits passera toujous un 32 bits sur la pile, ou plusieurs, mais jamais de 8 ni 16 pour laisser le registre ESP aligne sur 4."
Tu pourrais me réexpliquer ça ?
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
25 nov. 2003 à 09:16
170 est le grand factoriel possible tant qu'on travaille avec des nombres 'ordinaires', le cas ici. Ceci dit, le stack overflow est toujours a prendre en compte car on ne sait pas le contexte d'appel de sa fonction.
'Recursif plus joli', Garslouche ferait-il dans les Arts Deco ? oh oh...
Plus serieux, la remarque sur unsigned est judicieuse. Note qu'un compilo pour 32 bits passera toujous un 32 bits sur la pile, ou plusieurs, mais jamais de 8 ni 16 pour laisser le registre ESP aligne sur 4.
Pour conclure, toujours essayer de passer en iteratif un algo recursif. Des auteurs comme Sedgewick, Delanoy etc en donnent de tres bons exemples dans leurs bouquins.
Bossez bien.
garslouche Messages postés 583 Date d'inscription mardi 26 novembre 2002 Statut Membre Dernière intervention 29 mai 2015 1
25 nov. 2003 à 07:37
Si je peux me permettre la version récursive est plus jolie (mais les goûts et les couleurs...)

Mais surtout les risques de stack overflow sont pour ainsi dire inexisants. Puisque même en double le plus grand factoriel possible est 170! = 7.2574156153080e+306

Par contre je te conseillerais au moins de passer ton paramètre en unsigned int (ou plutot en unsigned char puisqu'il ne sert à rien d'aller au delà de 170) pour éviter les valeurs négatives qui ferait ton algo ne se termine pas !

Par contre pour ce qui est de l'efficacité - aucun doute - la méthode itérative est meilleure (du moins en C/C++)
cs_Koreth Messages postés 3 Date d'inscription lundi 24 novembre 2003 Statut Membre Dernière intervention 27 novembre 2003
24 nov. 2003 à 23:09
Modification: apres avoir lu votre CARTE DE VISITE, je m'apercois ke c a une personne importante a qui g affaire et je suis touché par un commentaire de vous. Felicitations pr ttes ces sources merci encore du commentaires et encore bravo surtout!!!!!!
cs_Koreth Messages postés 3 Date d'inscription lundi 24 novembre 2003 Statut Membre Dernière intervention 27 novembre 2003
24 nov. 2003 à 23:06
oui je c k'en iteratif c plus simple et pas de stack overflow mais bon deja now avec no machines c de moins en moins riské mais bon passons la dessus....merci pr ton conseil je le prend au serieux ct surtout un exemple pr illustrer les fonction recursives aprs y'en a de plus complexes avec lesquels je suis sur k'on ferait peter le quota d'overflow lol

Merci pr le comment......


Seb
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
24 nov. 2003 à 22:57
Transforme en iteratif qui sera bien plus rapide et aucun risque de stack overflow.
Rejoignez-nous