Quelle est la fonction factorielle la plus rapide en JavaScript?

cherche une implémentation très rapide de la fonction factorielle en JavaScript. Tout laisse penser?

75
demandé sur Jenny O'Reilly 2010-10-18 16:40:18

30 réponses

Vous pouvez rechercher (1...100)! sur WolframAlpha pour pré-calculer la séquence factorielle.

les 100 premiers nombres sont:

1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000, 1124000727777607680000, 25852016738884976640000, 620448401733239439360000, 15511210043330985984000000, 403291461126605635584000000, 10888869450418352160768000000, 304888344611713860501504000000, 8841761993739701954543616000000, 265252859812191058636308480000000, 8222838654177922817725562880000000, 263130836933693530167218012160000000, 8683317618811886495518194401280000000, 295232799039604140847618609643520000000, 10333147966386144929666651337523200000000, 371993326789901217467999448150835200000000, 13763753091226345046315979581580902400000000, 523022617466601111760007224100074291200000000, 20397882081197443358640281739902897356800000000, 815915283247897734345611269596115894272000000000, 33452526613163807108170062053440751665152000000000, 1405006117752879898543142606244511569936384000000000, 60415263063373835637355132068513997507264512000000000, 2658271574788448768043625811014615890319638528000000000, 119622220865480194561963161495657715064383733760000000000, 5502622159812088949850305428800254892961651752960000000000, 258623241511168180642964355153611979969197632389120000000000, 12413915592536072670862289047373375038521486354677760000000000, 608281864034267560872252163321295376887552831379210240000000000, 30414093201713378043612608166064768844377641568960512000000000000, 1551118753287382280224243016469303211063259720016986112000000000000, 80658175170943878571660636856403766975289505440883277824000000000000, 4274883284060025564298013753389399649690343788366813724672000000000000, 230843697339241380472092742683027581083278564571807941132288000000000000, 12696403353658275925965100847566516959580321051449436762275840000000000000, 710998587804863451854045647463724949736497978881168458687447040000000000000, 40526919504877216755680601905432322134980384796226602145184481280000000000000, 2350561331282878571829474910515074683828862318181142924420699914240000000000000, 138683118545689835737939019720389406345902876772687432540821294940160000000000000, 8320987112741390144276341183223364380754172606361245952449277696409600000000000000, 507580213877224798800856812176625227226004528988036003099405939480985600000000000000, 31469973260387937525653122354950764088012280797258232192163168247821107200000000000000, 1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000, 126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000, 8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000, 544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000, 36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000, 2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000, 171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000, 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000, 850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000, 61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000, 4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000, 330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000, 24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000, 1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000, 145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000, 11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000, 894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000, 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000, 5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000, 475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000, 39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000, 3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000, 281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000, 24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000, 2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000, 185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000, 16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000, 1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000, 135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000, 12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000, 1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000, 108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000, 10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000, 991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000, 96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000, 9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000, 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

si vous voulez encore calculer les valeurs vous-même, vous pouvez utiliser memoization :

var f = [];
function factorial (n) {
  if (n == 0 || n == 1)
    return 1;
  if (f[n] > 0)
    return f[n];
  return f[n] = factorial(n-1) * n;
} ​

modifier: 21.08.2014

Solution 2

j'ai pensé qu'il serait utile d'ajouter un exemple de travail de paresseux itératif fonction factorielle qui utilise grands nombres pour obtenir exact avec memoization et cache comparaison

var f = [new BigNumber("1"), new BigNumber("1")];
var i = 2;
function factorial(n)
{
  if (typeof f[n] != 'undefined')
    return f[n];
  var result = f[i-1];
  for (; i <= n; i++)
      f[i] = result = result.multiply(i.toString());
  return result;
}
var cache = 100;
//due to memoization following line will cache first 100 elements
factorial(cache);

je suppose que vous utiliseriez une sorte de fermeture pour limiter la visibilité des noms variables.

Ref : BigNumber Bac À Sable : JsFiddle

89
répondu Margus 2017-05-23 12:02:56

, Vous devez utiliser une boucle.

voici deux versions référencées en calculant le factoriel de 100 pour 10.000 fois.

Récursive

function rFact(num)
{
    if (num === 0)
      { return 1; }
    else
      { return num * rFact( num - 1 ); }
}

itératif

function sFact(num)
{
    var rval=1;
    for (var i = 2; i <= num; i++)
        rval = rval * i;
    return rval;
}

Live at: http://jsfiddle.net/xMpTv /

mes résultats montrent:

- Recursive ~ 150 millisecondes

- itératif ~ 5 millisecondes..

79
répondu Gabriele Petrioli 2014-05-09 19:21:50

je pense toujours que la réponse de Margus est la meilleure. Cependant, si vous voulez calculer les facteurs de nombres dans l'intervalle 0 à 1 (c.-à-d. la fonction gamma) aussi bien, alors vous ne pouvez pas utiliser cette approche parce que la table de recherche devra contenir des valeurs infinies.

cependant, vous can se rapprochent des valeurs des facteurs, et il est assez rapide, plus rapide que récursivement se appelant ou en boucle au moins (en particulier quand les valeurs commencez à obtenir les plus grands).

une bonne méthode d'approximation est celle de Lanczos

voici une implémentation en JavaScript (adapté d'une calculatrice que j'ai écrite il y a des mois):

function factorial(op) {
 // Lanczos Approximation of the Gamma Function
 // As described in Numerical Recipes in C (2nd ed. Cambridge University Press, 1992)
 var z = op + 1;
 var p = [1.000000000190015, 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 1.208650973866179E-3, -5.395239384953E-6];

 var d1 = Math.sqrt(2 * Math.PI) / z;
 var d2 = p[0];

 for (var i = 1; i <= 6; ++i)
  d2 += p[i] / (z + i);

 var d3 = Math.pow((z + 5.5), (z + 0.5));
 var d4 = Math.exp(-(z + 5.5));

 d = d1 * d2 * d3 * d4;

 return d;
}

vous pouvez maintenant faire des choses fraîches comme factorial(0.41) , etc Cependant la précision pourrait être un peu off, après tout, il est une approximation du résultat.

27
répondu Waleed Amjad 2010-10-18 13:00:30

table de recherche est la voie évidente à suivre, si vous travaillez avec des nombres naturels. Pour calculer n'importe quel factoriel en temps réel, vous pouvez l'accélérer avec un cache, sauvant les nombres que vous avez calculés avant. Quelque chose comme:

factorial = (function() {
    var cache = {},
        fn = function(n) {
            if (n === 0) {
                return 1;
            } else if (cache[n]) {
                return cache[n];
            }
            return cache[n] = n * fn(n -1);
        };
    return fn;
})();

Vous pouvez précalculer certaines valeurs, afin d'accélérer encore plus.

16
répondu xPheRe 2017-03-09 19:28:58

voici ma solution:

function fac(n){
    return(n<2)?1:fac(n-1)*n;
}

C'est la façon la plus simple (moins de caractères / lignes) j'ai trouvé, seulement une fonction avec une ligne de code.


modifier:

Si vous voulez vraiment sauver quelques chars, vous pouvez aller avec un fonction de flèche (21 octets) :

f=n=>(n<2)?1:f(n-1)*n
10
répondu Toni Almeida 2016-08-17 09:12:41

fonction de récursion courte et facile (vous pourriez le faire avec une boucle, aussi, mais je ne pense pas que cela ferait une différence dans la performance):

function factorial (n){
  if (n==0 || n==1){
    return 1;
  }
  return factorial(n-1)*n;
} 

pour un très grand n, Vous pouvez utiliser le approximation de stirlings - mais cela ne vous donnera qu'une valeur approximative.

EDIT: un commentaire sur pourquoi je suis un downvote pour cela aurait été sympa...

EDIT2: ce serait la solution utilisant une boucle (qui serait le meilleur choix):

function factorial (n){
  j = 1;
  for(i=1;i<=n;i++){
    j = j*i;
  }
  return j;
}

je pense que la meilleure solution serait d'utiliser les valeurs cachées, comme Margus l'a mentionné et d'utiliser le approximation de stirlings pour des valeurs plus grandes (supposé que vous devez être really fast et ne pas avoir à être que exact sur de tels grands nombres).

8
répondu oezi 2015-10-04 07:12:11

voici, le memoizer, qui prend n'importe quelle fonction d'argument simple et le mémoize. Il s'avère être légèrement plus rapide que la solution de @xPheRe , y compris la limite sur la taille du cache et la vérification associée, parce que j'utilise courtcircuitation et ainsi de suite.

function memoize(func, max) {
    max = max || 5000;
    return (function() {
        var cache = {};
        var remaining = max;
        function fn(n) {
            return (cache[n] || (remaining-- >0 ? (cache[n]=func(n)) : func(n)));
        }
        return fn;
    }());
}

function fact(n) {
    return n<2 ? 1: n*fact(n-1);
}

// construct memoized version
var memfact = memoize(fact,170);

// xPheRe's solution
var factorial = (function() {
    var cache = {},
        fn = function(n) {
            if (n === 0) {
                return 1;
            } else if (cache[n]) {
                return cache[n];
            }
            return cache[n] = n * fn(n -1);
        };
    return fn;
}());

environ 25x plus rapide sur ma machine en Chrome que la version recursive, et 10% plus rapide que xPheRe.

7
répondu Phil H 2017-05-23 12:18:24

je suis tombé sur ce post. Inspiré par toutes les contributions ici, je suis venu avec ma propre version, qui a deux caractéristiques que je n'ai pas vu discuté avant: 1) Une vérification pour s'assurer que l'argument est un entier non négatif 2) Création d'une unité à partir du cache et de la fonction pour en faire un bit de code autonome. Pour le plaisir, j'ai essayé de le rendre aussi compact que possible. Certains le trouvent élégant, d'autres le trouvent terriblement obscur. Bref, le voilà:

var fact;
(fact = function(n){
    if ((n = parseInt(n)) < 0 || isNaN(n)) throw "Must be non-negative number";
    var cache = fact.cache, i = cache.length - 1;
    while (i < n) cache.push(cache[i++] * i);
    return cache[n];
}).cache = [1];

vous pouvez soit pré-remplir le cache, soit permettre qu'il soit rempli au fur et à mesure que les appels passent. Mais l'élément initial (pour les faits (0) doit être présent ou il se brisera.

Enjoy:)

5
répondu Roland Bouman 2012-03-07 21:30:02

une seule ligne avec ES6

const factorial =(n) =>!(n > 1) ? 1 : factorial(n - 1) * n;

const factorial =(n) =>!(n > 1) ? 1 : factorial(n - 1) * n;


function print(value) {
  document.querySelector('.result').innerHTML = value;
}
.result {
  margin-left: 10px;
}
<input onkeyup="print(factorial(this.value))" type="number"/>

<span class="result">......</span>
5
répondu Abdennour TOUMI 2017-11-03 18:35:09

il est très simple d'utiliser ES6

const factorial = n => n ? (n * factorial(n-1)) : 1;

voir un exemple ici

4
répondu joseluiscc 2016-11-05 05:40:58

le code pour calculer factoriel dépend de vos besoins.

  1. Êtes-vous préoccupé par le débordement?
  2. quelle gamme d'entrées aurez-vous?
  3. est-il plus important pour vous de minimiser la taille ou le temps?
  4. Qu'allez-vous faire du factoriel?

en ce qui concerne les points 1 et 4, il est souvent plus utile d'avoir une fonction d'évaluation de la log du factoriel directement plutôt que d'avoir une fonction pour évaluer le factoriel lui-même.

Voici une blog post qui traite de ces questions. Voici un certain C# code pour le calcul log factoriel qui serait trivial à port à JavaScript. Mais ce n'est peut-être pas le mieux pour vos besoins selon vos réponses aux questions ci-dessus.

3
répondu John D. Cook 2010-10-18 13:25:08

C'est une version compacte en boucle

function factorial( _n )
{
    var _p = 1 ;
    while( _n > 0 ) { _p *= _n-- ; }
    return _p ;
}

ou vous pourriez outrepasser L'objet mathématique (version récursive):

Math.factorial = function( _x )  { return _x <= 1 ? 1 : _x * Math.factorial( --_x ) ; }

ou joindre les deux approches ...

3
répondu Sandro Rosa 2017-03-11 10:35:44

Juste pour être complet, voici une version récursive qui permettrait optimisation de l'appel de queue. Je ne suis pas sûr que les optimisations des appels de queue soient effectuées en JavaScript..

function rFact(n, acc)
{
    if (n == 0 || n == 1) return acc; 
    else return rFact(n-1, acc*n); 
}

pour l'appeler:

rFact(x, 1);
2
répondu Robert Jeppesen 2010-11-19 06:32:33

il s'agit d'une solution itérative qui utilise moins d'espace dans la pile et économise les valeurs calculées précédemment d'une manière auto-mémorielle:

Math.factorial = function(n){
    if(this.factorials[n]){ // memoized
        return this.factorials[n];
    }
    var total=1;
    for(var i=n; i>0; i--){
        total*=i;
    }
    this.factorials[n] = total; // save
    return total;
};
Math.factorials={}; // store

notez aussi que j'ajoute ceci à l'objet mathématique qui est un objet littéral donc il n'y a pas de prototype. Il suffit plutôt de les lier directement à la fonction.

2
répondu b-h- 2012-03-05 19:02:39

je crois que ce qui suit est le morceau de code le plus durable et efficace des commentaires ci-dessus. Vous pouvez l'utiliser dans votre architecture js d'application globale... et, ne vous inquiétez pas de l'écrire dans des espaces de noms multiples (puisque c'est une tâche qui n'a probablement pas besoin de beaucoup d'augmentation). J'ai inclus 2 noms de méthode (basé sur la préférence), mais les deux peuvent être utilisés comme ils sont juste des références.

Math.factorial = Math.fact = function(n) {
    if (isNaN(n)||n<0) return undefined;
    var f = 1; while (n > 1) {
        f *= n--;
    } return f;
};
2
répondu Joe Johnson 2012-03-19 18:03:51
// if you don't want to update the Math object, use `var factorial = ...`
Math.factorial = (function() {
    var f = function(n) {
        if (n < 1) {return 1;}  // no real error checking, could add type-check
        return (f[n] > 0) ? f[n] : f[n] = n * f(n -1);
    }
    for (i = 0; i < 101; i++) {f(i);} // precalculate some values
    return f;
}());

factorial(6); // 720, initially cached
factorial[6]; // 720, same thing, slightly faster access, 
              // but fails above current cache limit of 100
factorial(100); // 9.33262154439441e+157, called, but pulled from cache
factorial(142); // 2.6953641378881614e+245, called
factorial[141]; // 1.89814375907617e+243, now cached

Cela fait la mise en cache des 100 premières valeurs à la volée, et n'introduit pas de variable externe dans scope pour le cache, stockant les valeurs comme propriétés de l'objet de fonction lui-même, ce qui signifie que si vous savez que factorial(n) a déjà été calculé, vous pouvez simplement l'appeler factorial[n] , ce qui est légèrement plus efficace. L'exécution de ces 100 premières valeurs prendra moins de milliseconde temps dans les navigateurs modernes.

2
répondu Scott Sauyet 2012-03-23 13:43:52

Voici une implémentation qui calcule les facteurs positifs et négatifs. C'est simple et rapide.

var factorial = function(n) {
  return n > 1
    ? n * factorial(n - 1)
    : n < 0
        ? n * factorial(n + 1)
        : 1;
}
2
répondu Ilia Bykow 2012-07-31 03:22:23

Voici mon code

function factorial(num){
    var result = num;
    for(i=num;i>=2;i--){
        result = result * (i-1);
    }
    return result;
}
2
répondu cse031sust02 2014-01-03 16:50:38
function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n)
}

fourni par http://javascript.info/tutorial/number-math comme un moyen simple d'évaluer si un objet est un entier approprié pour le calcul.

var factorials=[[1,2,6],3];

un ensemble simple de factoriels Mémoïsés qui nécessitent des calculs redondants, peut être traité avec" multiplier par 1", ou sont un chiffre qui est une équation simple ne vaut pas la peine de traitement en direct.

var factorial = (function(memo,n) {
    this.memomize = (function(n) {
        var ni=n-1;
        if(factorials[1]<n) {
            factorials[0][ni]=0;
            for(var factorial_index=factorials[1]-1;factorials[1]<n;factorial_index++) {
                factorials[0][factorials[1]]=factorials[0][factorial_index]*(factorials[1]+1);
                factorials[1]++;
            }
        }
    });
    this.factorialize = (function(n) {
        return (n<3)?n:(factorialize(n-1)*n);
    });
    if(isNumeric(n)) {
        if(memo===true) {
            this.memomize(n);
            return factorials[0][n-1];
        }
        return this.factorialize(n);
    }
    return factorials;
});

après avoir examiné les entrées des autres membres (à l'exclusion de L'avis de journal, bien que je puisse mettre en œuvre que plus tard) je suis allé de l'avant et a jeté ensemble un script qui est assez simple. J'ai commencé avec un simple exemple JavaScript OOP inculte et j'ai construit une petite classe pour gérer les factoriels. J'ai alors mis en œuvre ma version de la Memoization qui a été suggérée ci-dessus. J'ai également mis en œuvre la Factorialisation en sténo-graphie mais j'ai fait un petit ajustement d'erreur; j'ai changé le "n<2" en "n<3". "n<2" traiterait toujours n = 2 qui serait un déchet, parce que vous itéreriez pour un 2*1=2; c'est un déchet à mon avis. Je l'ai modifié en "n<3"; parce que si n est 1 ou 2 il retournera tout simplement n, s'il est 3 ou plus il évaluera normalement. Bien sûr, comme les règles s'appliquent, j'ai placé mes fonctions dans l'ordre décroissant de l'exécution supposée. J'ai ajouté l'option bool(true|false) pour permettre une modification rapide entre memo'ED et l'exécution normale (vous ne savez jamais quand vous voulez échanger sur votre page sans avoir à changer le "style"") Comme je l'ai dit plus tôt, la variable factorielles memoized est définie avec les 3 positions de départ, en prenant 4 caractères, et en minimisant les calculs inutiles. Tout ce qui passe après la troisième itération vous manipulez les maths à deux chiffres plus. Je me suis dit que si vous aviez assez de stickler à ce sujet, vous tourneriez sur une table factorielle (telle qu'implémentée).

Qu'est-ce que j'ai prévu après ça? stockage local et / session pour permettre une mise en cache au cas par cas du nécessaire itérations, traitant essentiellement de la question de la" table " mentionnée ci-dessus. Cela permettrait également d'économiser massivement de l'espace côté base de données et serveur. Cependant, si vous allez avec localStorage vous seriez essentiellement aspirer l'espace sur votre ordinateur des utilisateurs simplement pour stocker une liste de nombres et faire leur écran regarder plus rapidement, cependant sur une longue période de temps avec un besoin immense ce serait lent. Je pense que sessionStorage (dégagement après les feuilles de Tab) serait une bien meilleure route. Éventuellement combiner cela avec une auto équilibrage du serveur / cache dépendant local? L'Utilisateur a a besoin de x itérations. L'utilisateur B besoin d'Y itérations. X+Y / 2=montant nécessaire caché localement. Puis il suffit de détecter et bidouiller avec le temps de charge et les repères de temps d'exécution en direct pour chaque utilisateur jusqu'à ce qu'il s'ajuste à l'optimisation pour le site lui-même. Merci!

Edit 3:

var f=[1,2,6];
var fc=3;
var factorial = (function(memo) {
    this.memomize = (function(n) {
        var ni=n-1;
        if(fc<n) {
            for(var fi=fc-1;fc<n;fi++) {
                f[fc]=f[fi]*(fc+1);
                fc++;
            }
        }
        return f[ni];
    });

    this.factorialize = (function(n) {
        return (n<3)?n:(factorialize(n-1)*n);
    });

    this.fractal = (function (functio) {
        return function(n) {
            if(isNumeric(n)) {
                return functio(n);
            }
            return NaN;
        }
    });

    if(memo===true) {
        return this.fractal(memomize);
    }
    return this.fractal(factorialize);
});

cette édition implémente une autre suggestion de pile et me permet d'appeler la fonction comme factorielle(vrai)(5), qui était un de mes objectifs. : 3 j'ai aussi supprimé quelques assignations inutiles, et raccourci quelques noms de variables non-publiques.

2
répondu Sir Christopher Michael-Don Ro 2016-05-10 23:56:47

exploitant le fait que Number.MAX_VALUE < 171! , nous pouvons simplement utiliser un table de recherche complète composé de seulement 171 éléments de réseau compact prenant moins de 1,4 kilo-octets de mémoire.

Une recherche rapide de la fonction avec le runtime complexité O(1) et minimal d'accès au tableau les frais généraux de l'151960920" serait ensuite comme suit:

// Lookup table for n! for 0 <= n <= 170:
const factorials = [1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368e3,20922789888e3,355687428096e3,6402373705728e3,121645100408832e3,243290200817664e4,5109094217170944e4,1.1240007277776077e21,2.585201673888498e22,6.204484017332394e23,1.5511210043330986e25,4.0329146112660565e26,1.0888869450418352e28,3.0488834461171387e29,8.841761993739702e30,2.6525285981219107e32,8.222838654177922e33,2.631308369336935e35,8.683317618811886e36,2.9523279903960416e38,1.0333147966386145e40,3.7199332678990125e41,1.3763753091226346e43,5.230226174666011e44,2.0397882081197444e46,8.159152832478977e47,3.345252661316381e49,1.40500611775288e51,6.041526306337383e52,2.658271574788449e54,1.1962222086548019e56,5.502622159812089e57,2.5862324151116818e59,1.2413915592536073e61,6.082818640342675e62,3.0414093201713376e64,1.5511187532873822e66,8.065817517094388e67,4.2748832840600255e69,2.308436973392414e71,1.2696403353658276e73,7.109985878048635e74,4.0526919504877214e76,2.3505613312828785e78,1.3868311854568984e80,8.32098711274139e81,5.075802138772248e83,3.146997326038794e85,1.98260831540444e87,1.2688693218588417e89,8.247650592082472e90,5.443449390774431e92,3.647111091818868e94,2.4800355424368305e96,1.711224524281413e98,1.1978571669969892e100,8.504785885678623e101,6.1234458376886085e103,4.4701154615126844e105,3.307885441519386e107,2.48091408113954e109,1.8854947016660504e111,1.4518309202828587e113,1.1324281178206297e115,8.946182130782976e116,7.156945704626381e118,5.797126020747368e120,4.753643337012842e122,3.945523969720659e124,3.314240134565353e126,2.81710411438055e128,2.4227095383672734e130,2.107757298379528e132,1.8548264225739844e134,1.650795516090846e136,1.4857159644817615e138,1.352001527678403e140,1.2438414054641308e142,1.1567725070816416e144,1.087366156656743e146,1.032997848823906e148,9.916779348709496e149,9.619275968248212e151,9.426890448883248e153,9.332621544394415e155,9.332621544394415e157,9.42594775983836e159,9.614466715035127e161,9.90290071648618e163,1.0299016745145628e166,1.081396758240291e168,1.1462805637347084e170,1.226520203196138e172,1.324641819451829e174,1.4438595832024937e176,1.588245541522743e178,1.7629525510902446e180,1.974506857221074e182,2.2311927486598138e184,2.5435597334721877e186,2.925093693493016e188,3.393108684451898e190,3.969937160808721e192,4.684525849754291e194,5.574585761207606e196,6.689502913449127e198,8.094298525273444e200,9.875044200833601e202,1.214630436702533e205,1.506141741511141e207,1.882677176888926e209,2.372173242880047e211,3.0126600184576594e213,3.856204823625804e215,4.974504222477287e217,6.466855489220474e219,8.47158069087882e221,1.1182486511960043e224,1.4872707060906857e226,1.9929427461615188e228,2.6904727073180504e230,3.659042881952549e232,5.012888748274992e234,6.917786472619489e236,9.615723196941089e238,1.3462012475717526e241,1.898143759076171e243,2.695364137888163e245,3.854370717180073e247,5.5502938327393044e249,8.047926057471992e251,1.1749972043909107e254,1.727245890454639e256,2.5563239178728654e258,3.80892263763057e260,5.713383956445855e262,8.62720977423324e264,1.3113358856834524e267,2.0063439050956823e269,3.0897696138473508e271,4.789142901463394e273,7.471062926282894e275,1.1729568794264145e278,1.853271869493735e280,2.9467022724950384e282,4.7147236359920616e284,7.590705053947219e286,1.2296942187394494e289,2.0044015765453026e291,3.287218585534296e293,5.423910666131589e295,9.003691705778438e297,1.503616514864999e300,2.5260757449731984e302,4.269068009004705e304,7.257415615307999e306];

// Lookup function:
function factorial(n) {
  return factorials[n] || (n > 170 ? Infinity : NaN);
}

// Test cases:
console.log(factorial(NaN));       // NaN
console.log(factorial(-Infinity)); // NaN
console.log(factorial(-1));        // NaN
console.log(factorial(0));         // 1
console.log(factorial(170));       // 7.257415615307999e+306 < Number.MAX_VALUE
console.log(factorial(171));       // Infinity > Number.MAX_VALUE
console.log(factorial(Infinity));  // Infinity

c'est aussi précis et aussi vite qu'il obtient en utilisant le type de données Number . Le calcul de la table de recherche en Javascript - comme d'autres réponses le suggèrent-réduira la précision lorsque n! > Number.MAX_SAFE_INTEGER .

compresser la table runtime via gzip réduit sa taille sur disque d'environ 3,6 à 1,8 kilooctets.

2
répondu le_m 2017-11-23 04:13:03

Voici une solution:

function factorial(number) {
  total = 1
  while (number > 0) {
    total *= number
    number = number - 1
  }
  return total
}
2
répondu Erika Smith 2018-01-23 03:12:52

En voici un que j'ai fait moi-même, n'utilisez pas les numéros de plus de 170 ou de moins de 2.

function factorial(x){
 if((!(isNaN(Number(x)))) && (Number(x)<=170) && (Number(x)>=2)){
  x=Number(x);for(i=x-(1);i>=1;--i){
   x*=i;
  }
 }return x;
}
1
répondu TheBestGuest 2013-05-18 19:17:10

la boucle mise en cache devrait être la plus rapide (au moins lorsqu'elle est appelée plusieurs fois)

var factorial = (function() {
  var x =[];

  return function (num) {
    if (x[num] >0) return x[num];
    var rval=1;
    for (var i = 2; i <= num; i++) {
        rval = rval * i;
        x[i] = rval;
    }
    return rval;
  }
})();
1
répondu Сухой27 2014-03-20 14:27:38

ce serait probablement très simple au début et peut-être à partir de ce court code que vous le définiriez mieux en fonction de vos besoins:

<body>

    <button  onclick="fact()">Open the Prompt</button>
    <h2 id="output"></h2>

    <script>

    function fact(){ 
        var enter=prompt("Enter You Factorial Number Bellow :","");
        var Num_enter=Number(enter);

        for (var i=1,FactNumber=1;i<=Num_enter;i++){

        FactNumber=FactNumber*i;
        }

        if(Num_enter){ 
           document.getElementById("output").textContent="the factorial of "+ Num_enter + " is: "+Num_enter+"!= "+ FactNumber;
        }


     }

   </script>


 </body>
1
répondu hakim 2015-06-09 08:46:23
    function factorial(num){    
        var num=Number(num);
        if (num < 0){
            return "this is not a positive number";
        }
        else{

        for (i=2 , f=1 ; i<=num;i++){

        f=f*i;

        }

    return f;
    }
    }
    // the function assumes that a number < 0 is null and factorial of any word is considerate as factorial of 0 //

    console.log("-5! ="+factorial(-1));
    console.log("something ="+factorial("something"));
    console.log("15! ="+factorial(15));
    console.log("20! ="+factorial(20));
1
répondu hakim 2015-06-12 00:21:22

cela rendra le factoriel de n

function f(n) {
    var e = n;
    if (e == 1 | e == 0) return 1;
    while (n--) {
        if (n < 1)
            break;
        e *= n;
    }
    return e
}
1
répondu Ben Johnson mk2 2015-08-24 21:17:46

utilisant les fonctionnalités ES6, peut écrire le code sur une ligne & sans récursion :

var factorial=(n)=>Array.from({length:n},(v,k)=>k+1).reduce((a,b)=>a*b,1)
1
répondu Abdennour TOUMI 2016-07-24 21:15:29

C'est la façon la plus simple que je connaisse de faire une fonction factorielle

function factorial(num) {

    var result = 1;
    for(var i = 2; i<= num; i++) {
        result *= i;
    }
    return result;
}
1
répondu Timmy 2017-01-20 18:03:57

vous pouvez utiliser

function factorial(n) {
    return [...Array(n+1).keys()].slice(1).reduce( (a,b) => a * b, 1 );
}
1
répondu 太極者無極而生 2017-05-03 03:24:58

En voici un qui utilise les nouvelles fonctions javascript fill , map , reduce et constructor (et la syntaxe de Fat arrow):

Math.factorial = n => n === 0 ? 1 : Array(n).fill(null).map((e,i)=>i+1).reduce((p,c)=>p*c)

Edit: mise à jour pour gérer n === 0

1
répondu Ashley Coolman 2017-05-08 22:46:17