Factorial: примеры (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) помогает избегать ошибок, связанных с неявным приведением типов.
Расширенные примеры
Кэширование результатов (мемоизация)
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
Факториал через произведение массива
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
Функция с поддержкой дробных чисел через гамма-функцию
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
Асинхронный факториал с задержкой
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 нет встроенной функции, требуется ручная реализация. Риск переполнения целого типа.