Factorial: примеры (JAVASCRIPT)

JavaScript вычисление факториала: примеры и методы
Раздел: Примеры кода, Рекурсия
factorial(n: Number): Number

Функция factorial в JavaScript

В JavaScript не существует встроенной функции factorial. Функция для вычисления факториала числа реализуется разработчиками самостоятельно, обычно в виде рекурсивной или итеративной функции. Факториал используется в комбинаторике, теории вероятностей, анализе алгоритмов и других разделах математики.

Аргумент функции — целое неотрицательное число n. Если передано нецелое число, оно округляется. Для отрицательных чисел факториал не определён, функция обычно возвращает NaN или генерирует ошибку.

Возвращаемое значение — факториал числа (произведение всех целых чисел от 1 до n). Для n = 0 возвращается 1 по определению. Для больших чисел (n > 170) результат может выходить за пределы точности типа Number, рекомендуется использовать BigInt.

Примеры использования

Рекурсивная реализация

function factorialRecursive(n) {
  if (n < 0) return NaN;
  if (n === 0) return 1;
  return n * factorialRecursive(n - 1);
}

console.log(factorialRecursive(5));
console.log(factorialRecursive(0));
console.log(factorialRecursive(-1));
120
1
NaN

Итеративная реализация с BigInt

function factorialIterativeBigInt(n) {
  if (typeof n !== 'bigint') n = BigInt(n);
  if (n < 0n) return NaN;
  let result = 1n;
  for (let i = 1n; i <= n; i++) {
    result *= i;
  }
  return result;
}

console.log(factorialIterativeBigInt(5));
console.log(factorialIterativeBigInt(20));
120n
2432902008176640000n

Похожие функции в JavaScript

Прямых аналогов factorial в стандартной библиотеке JavaScript нет. Можно рассматривать:

  • Math.gamma() — гамма-функция, связанная с факториалом соотношением Γ(n+1)=n!. Принимает дробные числа. Реализована не во всех браузерах.
  • Произведение массива через reduce — альтернативный способ вычисления факториала без явной функции. Удобен для демонстрации работы с массивами.

Для точных вычислений с большими числами предпочтительнее использовать рекурсию или цикл с BigInt. Гамма-функция подходит для нецелых аргументов.

Типичные ошибки

Рекурсия без условия остановки

function factorialError(n) {
  return n * factorialError(n - 1);
}
console.log(factorialError(5));
Uncaught RangeError: Maximum call stack size exceeded

Игнорирование точности больших чисел

function factorialNaive(n) {
  let result = 1;
  for (let i = 1; i <= n; i++) result *= i;
  return result;
}
console.log(factorialNaive(200));
Infinity

Некорректная обработка аргументов

function factorialNoCheck(n) {
  if (n === 0) return 1;
  return n * factorialNoCheck(n - 1);
}
console.log(factorialNoCheck(-1));
-0

Изменения в последних версиях

Поскольку функция factorial не является частью стандартной библиотеки JavaScript, изменения касаются не её, а возможностей языка, влияющих на реализацию:

  • С появлением BigInt в ES2020 стало возможным точно вычислять факториалы очень больших чисел (например, 1000!).
  • Оптимизация хвостовой рекурсии в некоторых движках позволяет безопаснее использовать рекурсивные реализации.
  • Строгий режим (use strict) помогает избегать ошибок, связанных с неявным приведением типов.

Расширенные примеры

Кэширование результатов (мемоизация)

Пример javascript
const factorialMemo = (function() {
  const cache = {0: 1};
  return function(n) {
    if (n < 0) return NaN;
    if (cache[n] !== undefined) return cache[n];
    cache[n] = n * factorialMemo(n - 1);
    return cache[n];
  };
})();

console.log(factorialMemo(10));
console.log(factorialMemo(5));
console.log(factorialMemo(12));
3628800
120
479001600

Факториал через произведение массива

Пример javascript
function factorialArray(n) {
  if (n < 0) return NaN;
  return Array.from({length: n}, (_, i) => i + 1)
    .reduce((acc, val) => acc * val, 1);
}
console.log(factorialArray(6));
console.log(factorialArray(1));
720
1

Функция с поддержкой дробных чисел через гамма-функцию

Пример javascript
function factorialGamma(n) {
  if (typeof Math.gamma !== 'undefined') {
    return Math.gamma(n + 1);
  }
  // Приближённая реализация через ряд Ланкоса
  const g = 7;
  const p = [
    0.99999999999980993, 676.5203681218851, -1259.1392167224028,
    771.32342877765313, -176.61502916214059, 12.507343278686905,
    -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7
  ];
  if (n < 0.5) {
    return Math.PI / (Math.sin(Math.PI * n) * factorialGamma(1 - n));
  }
  n--;
  let x = p[0];
  for (let i = 1; i < g + 2; i++) {
    x += p[i] / (n + i);
  }
  const t = n + g + 0.5;
  return Math.sqrt(2 * Math.PI) * Math.pow(t, n + 0.5) * Math.exp(-t) * x;
}
console.log(factorialGamma(5).toFixed(2));
console.log(factorialGamma(2.5).toFixed(4));
120.00
3.3234

Асинхронный факториал с задержкой

Пример javascript
async function factorialAsync(n) {
  if (n < 0) return Promise.reject(new Error('Negative number'));
  let result = 1n;
  for (let i = 1n; i <= n; i++) {
    result *= i;
    // Имитация асинхронной операции
    await new Promise(resolve => setTimeout(resolve, 10));
  }
  return result;
}

factorialAsync(5).then(console.log).catch(console.error);
120n

Альтернативы в других языках

Python: math.factorial()

import math
print(math.factorial(5))
print(math.factorial(0))
120
1

Принимает только неотрицательные целые числа, для отрицательных вызывает ValueError. Реализована на C, работает быстро.

PHP: gmp_fact()

<?
echo gmp_fact(5);
?>
120

Функция из расширения GMP для работы с большими числами. Возвращает число как строку.

C: цикл или рекурсия

#include 
long factorial(int n) {
    long result = 1;
    for (int i = 1; i <= n; i++) result *= i;
    return result;
}
int main() {
    printf("%ld\n", factorial(5));
    return 0;
}
120

В C нет встроенной функции, требуется ручная реализация. Риск переполнения целого типа.

JS factorial function comments

En
Factorial Recursively calculates the factorial of a non-negative integer