pub fn fac(n: i32) -> f64 {
if n < 0 {
panic!("fac not implemented for n < 0 (given value: n = {})", n);
} else if (n as usize) < FACTORIALS.len() {
FACTORIALS[n as usize]
} else {
std::f64::INFINITY
}
}
const FACTORIALS: [f64; 171] = [
1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0,
362880.0 , 3.6288000000000000e006, 3.9916800000000000e007,
4.7900160000000000e008, 6.2270208000000000e009, 8.7178291200000000e010,
1.3076743680000000e012, 2.0922789888000000e013, 3.5568742809600000e014,
6.4023737057280000e015, 1.2164510040883200e017, 2.4329020081766400e018,
5.1090942171709440e019, 1.1240007277776077e021, 2.5852016738884977e022,
6.2044840173323944e023, 1.5511210043330986e025, 4.0329146112660564e026,
1.0888869450418352e028, 3.0488834461171386e029, 8.8417619937397020e030,
2.6525285981219106e032, 8.2228386541779228e033, 2.6313083693369353e035,
8.6833176188118865e036, 2.9523279903960414e038, 1.0333147966386145e040,
3.7199332678990122e041, 1.3763753091226345e043, 5.2302261746660111e044,
2.0397882081197443e046, 8.1591528324789773e047, 3.3452526613163807e049,
1.4050061177528799e051, 6.0415263063373836e052, 2.6582715747884488e054,
1.1962222086548019e056, 5.5026221598120889e057, 2.5862324151116818e059,
1.2413915592536073e061, 6.0828186403426756e062, 3.0414093201713378e064,
1.5511187532873823e066, 8.0658175170943879e067, 4.2748832840600256e069,
2.3084369733924138e071, 1.2696403353658276e073, 7.1099858780486345e074,
4.0526919504877217e076, 2.3505613312828786e078, 1.3868311854568984e080,
8.3209871127413901e081, 5.0758021387722480e083, 3.1469973260387938e085,
1.9826083154044401e087, 1.2688693218588416e089, 8.2476505920824707e090,
5.4434493907744306e092, 3.6471110918188685e094, 2.4800355424368306e096,
1.7112245242814131e098, 1.1978571669969892e100, 8.5047858856786232e101,
6.1234458376886087e103, 4.4701154615126843e105, 3.3078854415193864e107,
2.4809140811395398e109, 1.8854947016660503e111, 1.4518309202828587e113,
1.1324281178206298e115, 8.9461821307829753e116, 7.1569457046263802e118,
5.7971260207473680e120, 4.7536433370128417e122, 3.9455239697206587e124,
3.3142401345653533e126, 2.8171041143805503e128, 2.4227095383672732e130,
2.1077572983795277e132, 1.8548264225739844e134, 1.6507955160908461e136,
1.4857159644817615e138, 1.3520015276784030e140, 1.2438414054641307e142,
1.1567725070816416e144, 1.0873661566567431e146, 1.0329978488239059e148,
9.9167793487094969e149, 9.6192759682482120e151, 9.4268904488832477e153,
9.3326215443944153e155, 9.3326215443944153e157, 9.4259477598383594e159,
9.6144667150351266e161, 9.9029007164861804e163, 1.0299016745145628e166,
1.0813967582402909e168, 1.1462805637347084e170, 1.2265202031961379e172,
1.3246418194518290e174, 1.4438595832024936e176, 1.5882455415227429e178,
1.7629525510902447e180, 1.974506857221074e0182, 2.2311927486598136e184,
2.5435597334721876e186, 2.9250936934930157e188, 3.3931086844518982e190,
3.9699371608087209e192, 4.6845258497542907e194, 5.5745857612076059e196,
6.6895029134491271e198, 8.0942985252734437e200, 9.8750442008336014e202,
1.2146304367025330e205, 1.5061417415111409e207, 1.8826771768889261e209,
2.3721732428800469e211, 3.0126600184576595e213, 3.8562048236258042e215,
4.9745042224772874e217, 6.4668554892204737e219, 8.4715806908788205e221,
1.1182486511960043e224, 1.4872707060906857e226, 1.9929427461615189e228,
2.6904727073180505e230, 3.6590428819525487e232, 5.0128887482749917e234,
6.9177864726194885e236, 9.6157231969410890e238, 1.3462012475717525e241,
1.8981437590761710e243, 2.6953641378881628e245, 3.8543707171800728e247,
5.5502938327393048e249, 8.0479260574719919e251, 1.1749972043909108e254,
1.7272458904546389e256, 2.5563239178728656e258, 3.8089226376305697e260,
5.7133839564458546e262, 8.6272097742332404e264, 1.3113358856834525e267,
2.0063439050956824e269, 3.0897696138473509e271, 4.7891429014633939e273,
7.4710629262828944e275, 1.1729568794264144e278, 1.8532718694937348e280,
2.9467022724950383e282, 4.7147236359920613e284, 7.5907050539472187e286,
1.2296942187394494e289, 2.0044015765453026e291, 3.2872185855342962e293,
5.4239106661315888e295, 9.0036917057784374e297, 1.5036165148649990e300,
2.5260757449731984e302, 4.2690680090047053e304, 7.2574156153079990e306
];
#[test]
fn test_fac() {
assert!(fac( 0) == 1.0);
assert!(fac( 1) == 1.0);
assert!(fac( 2) == 2.0);
assert!(fac(169) == 4.2690680090047053e304);
assert!(fac(170) == 7.257415615307999e306);
assert!(fac(171).is_infinite());
}
#[test]
#[should_panic]
fn test_fac_panic() {
fac(-1);
}
const INVERSE_FACTORIALS: [f64; 178] = [
1.0, 1.0, 0.5 , 1.6666666666666667e-001, 4.1666666666666667e-002,
8.3333333333333333e-003, 1.3888888888888889e-003, 1.9841269841269841e-004,
2.4801587301587302e-005, 2.7557319223985891e-006, 2.7557319223985891e-007,
2.5052108385441719e-008, 2.0876756987868099e-009, 1.6059043836821615e-010,
1.1470745597729725e-011, 7.6471637318198165e-013, 4.7794773323873853e-014,
2.8114572543455208e-015, 1.5619206968586226e-016, 8.2206352466243297e-018,
4.1103176233121649e-019, 1.9572941063391261e-020, 8.8967913924505733e-022,
3.8681701706306840e-023, 1.6117375710961183e-024, 6.4469502843844734e-026,
2.4795962632247975e-027, 9.1836898637955461e-029, 3.2798892370698379e-030,
1.1309962886447717e-031, 3.7699876288159056e-033, 1.2161250415535179e-034,
3.8003907548547436e-036, 1.1516335620771950e-037, 3.3871575355211618e-039,
9.6775929586318910e-041, 2.6882202662866364e-042, 7.2654601791530713e-044,
1.9119632050402819e-045, 4.9024697565135434e-047, 1.2256174391283858e-048,
2.9893108271424045e-050, 7.1174067312914393e-052, 1.6552108677421952e-053,
3.7618428812322618e-055, 8.3596508471828040e-057, 1.8173154015614791e-058,
3.8666285139605939e-060, 8.0554760707512373e-062, 1.6439747083165790e-063,
3.2879494166331581e-065, 6.4469596404571727e-067, 1.2397999308571486e-068,
2.3392451525606577e-070, 4.3319354677049217e-072, 7.8762463049180395e-074,
1.4064725544496499e-075, 2.4674957095607893e-077, 4.2543029475186023e-079,
7.2106829618959360e-081, 1.2017804936493227e-082, 1.9701319568021683e-084,
3.1776321883905941e-086, 5.0438606164930064e-088, 7.8810322132703225e-090,
1.2124664943492804e-091, 1.8370704459837582e-093, 2.7418961880354600e-095,
4.0322002765227352e-097, 5.8437685166996163e-099, 8.3482407381423090e-101,
1.1758085546679308e-102, 1.6330674370387928e-104, 2.2370786808750587e-106,
3.0230792984798090e-108, 4.0307723979730787e-110, 5.3036478920698404e-112,
6.8878544052855070e-114, 8.8305825708788551e-116, 1.1177952621365639e-117,
1.3972440776707049e-119, 1.7249926884823518e-121, 2.1036496201004290e-123,
2.5345176145788301e-125, 3.0172828744986072e-127, 3.5497445582336556e-129,
4.1276099514344832e-131, 4.7443792545223945e-133, 5.3913400619572665e-135,
6.0576854628733332e-137, 6.7307616254148146e-139, 7.3964413466096864e-141,
8.0396101593583548e-143, 8.6447421068369406e-145, 9.1965341562095113e-147,
9.6805622696942224e-149, 1.0083919030931482e-150, 1.0395792815393280e-152,
1.0607951852442123e-154, 1.0715102881254669e-156, 1.0715102881254669e-158,
1.0609012753717494e-160, 1.0400992895801465e-162, 1.0098051355147053e-164,
9.7096647645644744e-167, 9.2472997757756899e-169, 8.7238677129959339e-171,
8.1531473953233027e-173, 7.5492105512252803e-175, 6.9258812396562204e-177,
6.2962556724147458e-179, 5.6723024075808521e-181, 5.0645557210543322e-183,
4.4819077177471967e-185, 3.9314979980238567e-187, 3.4186939113250928e-189,
2.9471499235561145e-191, 2.5189315585949697e-193, 2.1346877615211607e-195,
1.7938552617824880e-197, 1.4948793848187400e-199, 1.2354375081146612e-201,
1.0126536951759518e-203, 8.2329568713492014e-206, 6.6394813478622592e-208,
5.3115850782898073e-210, 4.2155437129284185e-212, 3.3193257582113532e-214,
2.5932232486026197e-216, 2.0102505803121083e-218, 1.5463466002400833e-220,
1.1804172520916666e-222, 8.9425549400883835e-225, 6.7237255188634463e-227,
5.0177056110921241e-229, 3.7168189711793512e-231, 2.7329551258671700e-233,
1.9948577561074233e-235, 1.4455490986285676e-237, 1.0399633803083220e-239,
7.4283098593451574e-242, 5.2683048647837996e-244, 3.7100738484392955e-246,
2.5944572366708360e-248, 1.8017064143547472e-250, 1.2425561478308602e-252,
8.5106585467867134e-255, 5.7895636372698731e-257, 3.9118673224796440e-259,
2.6254143103890228e-261, 1.7502762069260152e-263, 1.1591233158450432e-265,
7.6258112884542314e-268, 4.9841903846106088e-270, 3.2364872627341615e-272,
2.0880562985381687e-274, 1.3384976272680569e-276, 8.5254625940640566e-279,
5.3958624013063649e-281, 3.3936241517650094e-283, 2.1210150948531309e-285,
1.3174006800330005e-287, 8.1321029631666700e-290, 4.9890202228016380e-292,
3.0420855017083159e-294, 1.8436881828535248e-296, 1.1106555318394728e-298,
6.6506319271824716e-301, 3.9587094804657569e-303, 2.3424316452460100e-305,
1.3779009677917706e-307, 8.0579003964431028e-310, 4.6848258118855249e-312,
2.7079917987777601e-314, 1.5563171257343449e-316, 8.8932407184819707e-319,
5.0529776809556651e-321, 2.8547896502574379e-323
];
pub fn inv_fac(n: i32) -> f64 {
if n < 0 {
panic!("inv_fac not implemented for n < 0 (given value: n = {})", n);
} else if (n as usize) < INVERSE_FACTORIALS.len() {
INVERSE_FACTORIALS[n as usize]
} else {
0.0
}
}
#[test]
fn test_inv_fac() {
assert!(inv_fac( 0) == 1.0);
assert!(inv_fac( 1) == 1.0);
assert!(inv_fac( 2) == 0.5);
assert!(inv_fac(177) == 2.8547896502574379e-323);
assert!(inv_fac(178) == 0.0);
}
#[test]
#[should_panic]
fn test_inv_fac_panic() {
inv_fac(-1);
}