use crate::utils::hidden_macros::trust_me;
#[cfg(not(NIGHTLY))]
extern "C" {
fn tgamma(x: f64) -> f64;
}
#[doc(hidden)]
#[inline]
#[cfg(not(NIGHTLY))]
pub fn gamma(x: f64) -> f64 {
unsafe { tgamma(x) }
}
#[doc(hidden)]
#[cfg(NIGHTLY)]
pub const gamma: fn(f64) -> f64 = f64::gamma;
#[doc(hidden)]
pub fn factorial(num: f64) -> f64 {
const ZERO: f64 = 0.0;
const MAX: f64 = 170.0;
if num < ZERO {
return f64::NAN;
}
if num.is_infinite() {
return f64::INFINITY;
}
if num.fract() != ZERO {
return f64::NAN;
}
if num > MAX {
return f64::INFINITY;
}
let index = trust_me!(num.to_int_unchecked::<usize>());
#[allow(clippy::indexing_slicing)]
FACTORIALS[index]
}
#[doc(hidden)]
const FACTORIALS: [f64; 171] = [
1.0,
1.0,
2.0,
6.0,
24.0,
120.0,
720.0,
5_040.0,
40_320.0,
362_880.0,
3_628_800.0,
39_916_800.0,
479_001_600.0,
6_227_020_800.0,
87_178_291_200.0,
1_307_674_368_000.0,
20_922_789_888_000.0,
355_687_428_096_000.0,
6_402_373_705_728_000.0,
1.216_451_004_088_32e17,
2.432_902_008_176_64e18,
5.109_094_217_170_944e19,
1.124_000_727_777_607_7e21,
2.585_201_673_888_498e22,
6.204_484_017_332_394e23,
1.551_121_004_333_098_6e25,
4.032_914_611_266_056_5e26,
1.088_886_945_041_835_2e28,
3.048_883_446_117_138_4e29,
8.841_761_993_739_701e30,
2.652_528_598_121_910_3e32,
8.222_838_654_177_922e33,
2.631_308_369_336_935e35,
8.683_317_618_811_886e36,
2.952_327_990_396_041_2e38,
1.033_314_796_638_614_4e40,
3.719_933_267_899_012e41,
1.376_375_309_122_634_3e43,
5.230_226_174_666_01e44,
2.039_788_208_119_744_2e46,
8.159_152_832_478_977e47,
3.345_252_661_316_380_3e49,
1.405_006_117_752_879_8e51,
6.041_526_306_337_383e52,
2.658_271_574_788_448_5e54,
1.196_222_208_654_801_9e56,
5.502_622_159_812_088_5e57,
2.586_232_415_111_681_8e59,
1.241_391_559_253_607_3e61,
6.082_818_640_342_675e62,
3.041_409_320_171_337_6e64,
1.551_118_753_287_382_2e66,
8.065_817_517_094_388e67,
4.274_883_284_060_025_5e69,
2.308_436_973_392_414e71,
1.269_640_335_365_827_6e73,
7.109_985_878_048_635e74,
4.052_691_950_487_722e76,
2.350_561_331_282_879e78,
1.386_831_185_456_898_6e80,
8.320_987_112_741_392e81,
5.075_802_138_772_248e83,
3.146_997_326_038_794e85,
1.982_608_315_404_44e87,
1.268_869_321_858_841_7e89,
8.247_650_592_082_472e90,
5.443_449_390_774_431e92,
3.647_111_091_818_868e94,
2.480_035_542_436_830_5e96,
1.711_224_524_281_413e98,
1.197_857_166_996_989e100,
8.504_785_885_678_622e101,
6.123_445_837_688_608e103,
4.470_115_461_512_683_4e105,
3.307_885_441_519_385_6e107,
2.480_914_081_139_539e109,
1.885_494_701_666_049_8e111,
1.451_830_920_282_858_4e113,
1.132_428_117_820_629_5e115,
8.946_182_130_782_973e116,
7.156_945_704_626_378e118,
5.797_126_020_747_366e120,
4.753_643_337_012_84e122,
3.945_523_969_720_657e124,
3.314_240_134_565_352e126,
2.817_104_114_380_549_4e128,
2.422_709_538_367_272_4e130,
2.107_757_298_379_527e132,
1.854_826_422_573_983_6e134,
1.650_795_516_090_845_2e136,
1.485_715_964_481_760_7e138,
1.352_001_527_678_402_3e140,
1.243_841_405_464_13e142,
1.156_772_507_081_640_9e144,
1.087_366_156_656_742_4e146,
1.032_997_848_823_905_2e148,
9.916_779_348_709_491e149,
9.619_275_968_248_206e151,
9.426_890_448_883_242e153,
9.332_621_544_394_41e155,
9.332_621_544_394_41e157,
9.425_947_759_838_354e159,
9.614_466_715_035_121e161,
9.902_900_716_486_175e163,
1.029_901_674_514_562_2e166,
1.081_396_758_240_290_3e168,
1.146_280_563_734_707_8e170,
1.226_520_203_196_137_3e172,
1.324_641_819_451_828_4e174,
1.443_859_583_202_492_8e176,
1.588_245_541_522_742_1e178,
1.762_952_551_090_243_7e180,
1.974_506_857_221_072_8e182,
2.231_192_748_659_812_3e184,
2.543_559_733_472_186e186,
2.925_093_693_493_014e188,
3.393_108_684_451_896_5e190,
3.969_937_160_808_719e192,
4.684_525_849_754_288_3e194,
5.574_585_761_207_603e196,
6.689_502_913_449_124e198,
8.094_298_525_273_44e200,
9.875_044_200_833_598e202,
1.214_630_436_702_532_5e205,
1.506_141_741_511_140_4e207,
1.882_677_176_888_925_4e209,
2.372_173_242_880_046e211,
3.012_660_018_457_658e213,
3.856_204_823_625_802_5e215,
4.974_504_222_477_285_5e217,
6.466_855_489_220_472e219,
8.471_580_690_878_817e221,
1.118_248_651_196_004e224,
1.487_270_706_090_685_2e226,
1.992_942_746_161_518e228,
2.690_472_707_318_049_5e230,
3.659_042_881_952_547e232,
5.012_888_748_274_99e234,
6.917_786_472_619_486e236,
9.615_723_196_941_086e238,
1.346_201_247_571_752e241,
1.898_143_759_076_17e243,
2.695_364_137_888_161_4e245,
3.854_370_717_180_070_6e247,
5.550_293_832_739_301e249,
8.047_926_057_471_987e251,
1.174_997_204_390_91e254,
1.727_245_890_454_637_6e256,
2.556_323_917_872_863_7e258,
3.808_922_637_630_567e260,
5.713_383_956_445_850_5e262,
8.627_209_774_233_235e264,
1.311_335_885_683_451_8e267,
2.006_343_905_095_681e269,
3.089_769_613_847_349e271,
4.789_142_901_463_391e273,
7.471_062_926_282_89e275,
1.172_956_879_426_413_8e278,
1.853_271_869_493_733_8e280,
2.946_702_272_495_037e282,
4.714_723_635_992_059e284,
7.590_705_053_947_215e286,
1.229_694_218_739_448_8e289,
2.004_401_576_545_301_5e291,
3.287_218_585_534_294_5e293,
5.423_910_666_131_586e295,
9.003_691_705_778_433e297,
1.503_616_514_864_998_3e300,
2.526_075_744_973_197e302,
4.269_068_009_004_702_7e304,
7.257_415_615_307_994e306,
];