use std::f64::consts::{E, PI}; /// Calculate the value of a factorial iteratively /// /// Can calculate up to 34! using native unsigned 128 bit integers. /// /// Example: /// ```rust /// use rusty_fib_facts::factorial; /// /// let valid = factorial(3); // Some(6) /// # assert_eq!(6, valid.unwrap()); /// /// let invalid = factorial(35); // None /// # assert!(invalid.is_none()); /// ``` #[inline] pub fn it_factorial(n: usize) -> Option { let mut total: u128 = 1; if matches!(n, 0 | 1) { Some(1u128) } else { for x in 1..=n { total = total.checked_mul(x as u128)?; } Some(total) } } /// Calculate the value of a factorial recursively /// /// Can calculate up to 34! using native unsigned 128 bit integers. /// /// Example: /// ```rust /// use rusty_fib_facts::factorial; /// /// let valid = factorial(3); // Some(6) /// # assert_eq!(6, valid.unwrap()); /// /// let invalid = factorial(35); // None /// # assert!(invalid.is_none()); /// ``` #[inline] pub fn factorial(n: usize) -> Option { if matches!(n, 0 | 1) { Some(1u128) } else { let prev = factorial(n - 1)?; (n as u128).checked_mul(prev) } } /// Approximates a factorial using Stirling's approximation /// /// Based on https://en.wikipedia.org/wiki/Stirling's_approximation /// /// Can approximate up to ~ 170.624! /// /// Example: /// ```rust /// use rusty_fib_facts::approx_factorial; /// /// let valid = approx_factorial(170.6); // Some(..) /// # assert!(valid.is_some()); /// /// let invalid = approx_factorial(171.0); // None /// # assert!(invalid.is_none()); /// ``` #[inline] pub fn approx_factorial(n: f64) -> Option { let power = (n / E).powf(n); let root = (PI * 2.0 * n).sqrt(); let res = power * root; if res >= std::f64::MIN && res <= std::f64::MAX { Some(res) } else { None } }