use crate::gammafn;
use crate::lgammacor;
use crate::nmath::*;
use crate::sinpi;
const XMAX: f64 = 2.532_737_276_080_075_8e305;
const DXREL: f64 = 1.490_116_119_384_765_6e-8;
pub fn lgammafn(x: f64) -> f64 {
lgammafn_sign(x, None)
}
pub fn lgammafn_sign(x: f64, sgn: Option<&mut i32>) -> f64 {
if let Some(sgn) = sgn {
*sgn = 1;
if x < 0.0 && ((-x).floor() % 2.0) == 0.0 {
*sgn = -1;
}
}
if x.is_nan() {
return ML_NAN;
}
if x <= 0.0 && x == x.trunc() {
return f64::INFINITY; }
let y = x.abs();
if y < 1e-306 {
return -y.ln();
}
if y <= 10.0 {
return gammafn(x).abs().ln();
}
if y > XMAX {
return f64::INFINITY;
}
if x > 0.0 {
if x > 1e17 {
x * (x.ln() - 1.0)
} else if x > 4934720.0 {
return M_LN_SQRT_2PI + (x - 0.5) * x.ln() - x;
} else {
return M_LN_SQRT_2PI + (x - 0.5) * x.ln() - x + lgammacor(x);
}
} else {
let sinpiy = sinpi(y).abs();
if sinpiy == 0.0 {
return ML_NAN;
}
let ans = M_LN_SQRT_2PI + (x - 0.5) * y.ln() - x - sinpiy.ln() - lgammacor(y);
if ((x - x.trunc() - 0.5) * ans / x).abs() < DXREL {
println!("** should NEVER happen! *** [lgamma.rs: Neg.int, y={}]", y);
return ML_NAN; }
ans
}
}