JavaScript Algorithms

Cálculo eficiente de factorial en JavaScript

Spread the love

Calcular factoriales es una tarea fundamental en programación, a menudo utilizada para demostrar técnicas de programación recursiva e iterativa. Si bien la recursión proporciona una solución elegante que refleja la definición matemática, puede sufrir limitaciones de rendimiento significativas para números más grandes debido a la sobrecarga de llamadas a funciones y posibles errores de desbordamiento de pila. Este artículo explora varios métodos para calcular factoriales en JavaScript, centrándose en la eficiencia y el manejo de números grandes.

Tabla de contenido

Factorial: Enfoque Recursivo

El enfoque recursivo traduce directamente la definición matemática de un factorial (n! = n * (n-1)!) en código:


function factorialRecursive(n) {
  if (n < 0) {
    throw new Error("El factorial no está definido para números negativos");
  } else if (n === 0) {
    return 1;
  } else {
    return n * factorialRecursive(n - 1);
  }
}

console.log(factorialRecursive(5)); // Salida: 120

Si bien es conciso y fácil de entender, este método es ineficiente para valores más grandes de n debido a las llamadas repetidas a funciones y posibles errores de desbordamiento de pila. La complejidad de tiempo y espacio son ambas O(n).

Factorial: Enfoque Iterativo

Un enfoque iterativo evita la sobrecarga de la recursión utilizando un bucle:


function factorialIterative(n) {
  if (n < 0) {
    throw new Error("El factorial no está definido para números negativos");
  } else if (n === 0) {
    return 1;
  } else {
    let result = 1;
    for (let i = 1; i <= n; i++) {
      result *= i;
    }
    return result;
  }
}

console.log(factorialIterative(5)); // Salida: 120

Este método es significativamente más rápido que la versión recursiva, con una complejidad de tiempo de O(n) y una complejidad de espacio constante, O(1).

Factorial: Enfoque Optimizado con BigInt

Para factoriales muy grandes, los números estándar de JavaScript pueden desbordarse. El tipo BigInt de JavaScript nos permite manejar enteros arbitrariamente grandes. Combinar esto con el enfoque iterativo proporciona la solución más robusta y eficiente:


function factorialOptimized(n) {
  if (n < 0) {
    throw new Error("El factorial no está definido para números negativos");
  } else if (n === 0n) {
    return 1n;
  } else {
    let result = 1n;
    for (let i = 1n; i <= n; i++) {
      result *= i;
    }
    return result;
  }
}

console.log(factorialOptimized(100n)); // Salida: Un BigInt muy grande que representa 100!

Tenga en cuenta el uso de n como literal BigInt (100n) y el uso de BigInt en toda la función. Esto garantiza resultados precisos incluso para factoriales extremadamente grandes.

Comparación de Rendimiento

El enfoque iterativo con BigInt ofrece el mejor rendimiento y evita problemas de desbordamiento. Si bien son posibles optimizaciones adicionales para números excepcionalmente grandes utilizando técnicas matemáticas más avanzadas, este enfoque es óptimo para la mayoría de las aplicaciones prácticas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *