Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:55:20

0001 //  Copyright John Maddock 2006.
0002 //  Use, modification and distribution are subject to the
0003 //  Boost Software License, Version 1.0. (See accompanying file
0004 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_MATH_SP_UC_FACTORIALS_HPP
0007 #define BOOST_MATH_SP_UC_FACTORIALS_HPP
0008 
0009 #ifdef _MSC_VER
0010 #pragma once
0011 #endif
0012 
0013 #include <boost/math/tools/config.hpp>
0014 #include <boost/math/tools/type_traits.hpp>
0015 #include <boost/math/tools/array.hpp>
0016 #include <boost/math/tools/numeric_limits.hpp>
0017 #include <boost/math/special_functions/math_fwd.hpp>
0018 
0019 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0020 #  ifdef _MSC_VER
0021 #    pragma warning(push) // Temporary until lexical cast fixed.
0022 #    pragma warning(disable: 4127 4701)
0023 #  endif
0024 #  include <boost/math/tools/convert_from_string.hpp>
0025 #  ifdef _MSC_VER
0026 #    pragma warning(pop)
0027 #  endif
0028 #endif
0029 
0030 
0031 #if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
0032 //
0033 // This is the only way we can avoid
0034 // warning: non-standard suffix on floating constant [-Wpedantic]
0035 // when building with -Wall -pedantic.  Neither __extension__
0036 // nor #pragma diagnostic ignored work :(
0037 //
0038 #pragma GCC system_header
0039 #endif
0040 
0041 namespace boost { namespace math
0042 {
0043 // Forward declarations:
0044 template <class T>
0045 struct max_factorial;
0046 //
0047 // see https://github.com/boostorg/math/issues/923
0048 // for the rationale behin using struct's for constexpr data:
0049 //
0050 template <class T, bool = true>
0051 struct unchecked_factorial_data;
0052 
0053 #ifdef BOOST_MATH_HAS_NVRTC
0054 
0055 // Need fwd decl
0056 template <typename T>
0057 BOOST_MATH_GPU_ENABLED inline T unchecked_factorial(unsigned i);
0058 
0059 #endif
0060 
0061 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0062 
0063 template <bool b>
0064 struct unchecked_factorial_data<float, b>
0065 {
0066 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0067    static constexpr boost::math::array<float, 35> factorials = { {
0068       1.0F,
0069       1.0F,
0070       2.0F,
0071       6.0F,
0072       24.0F,
0073       120.0F,
0074       720.0F,
0075       5040.0F,
0076       40320.0F,
0077       362880.0F,
0078       3628800.0F,
0079       39916800.0F,
0080       479001600.0F,
0081       6227020800.0F,
0082       87178291200.0F,
0083       1307674368000.0F,
0084       20922789888000.0F,
0085       355687428096000.0F,
0086       6402373705728000.0F,
0087       121645100408832000.0F,
0088       0.243290200817664e19F,
0089       0.5109094217170944e20F,
0090       0.112400072777760768e22F,
0091       0.2585201673888497664e23F,
0092       0.62044840173323943936e24F,
0093       0.15511210043330985984e26F,
0094       0.403291461126605635584e27F,
0095       0.10888869450418352160768e29F,
0096       0.304888344611713860501504e30F,
0097       0.8841761993739701954543616e31F,
0098       0.26525285981219105863630848e33F,
0099       0.822283865417792281772556288e34F,
0100       0.26313083693369353016721801216e36F,
0101       0.868331761881188649551819440128e37F,
0102       0.29523279903960414084761860964352e39F,
0103    }};
0104 #else
0105    static const boost::math::array<float, 35> factorials;
0106 #endif
0107 };
0108 
0109 template<bool b>
0110 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0111    constexpr boost::math::array<float, 35> unchecked_factorial_data<float, b>::factorials;
0112 #else
0113    const boost::math::array<float, 35> unchecked_factorial_data<float, b>::factorials = {{
0114       1.0F,
0115       1.0F,
0116       2.0F,
0117       6.0F,
0118       24.0F,
0119       120.0F,
0120       720.0F,
0121       5040.0F,
0122       40320.0F,
0123       362880.0F,
0124       3628800.0F,
0125       39916800.0F,
0126       479001600.0F,
0127       6227020800.0F,
0128       87178291200.0F,
0129       1307674368000.0F,
0130       20922789888000.0F,
0131       355687428096000.0F,
0132       6402373705728000.0F,
0133       121645100408832000.0F,
0134       0.243290200817664e19F,
0135       0.5109094217170944e20F,
0136       0.112400072777760768e22F,
0137       0.2585201673888497664e23F,
0138       0.62044840173323943936e24F,
0139       0.15511210043330985984e26F,
0140       0.403291461126605635584e27F,
0141       0.10888869450418352160768e29F,
0142       0.304888344611713860501504e30F,
0143       0.8841761993739701954543616e31F,
0144       0.26525285981219105863630848e33F,
0145       0.822283865417792281772556288e34F,
0146       0.26313083693369353016721801216e36F,
0147       0.868331761881188649551819440128e37F,
0148       0.29523279903960414084761860964352e39F,
0149    }};
0150 #endif
0151 
0152 // Definitions:
0153 template <>
0154 BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial<float>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
0155 {
0156    return unchecked_factorial_data<float>::factorials[i];
0157 }
0158 
0159 #else
0160 
0161 template <>
0162 BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial<float>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
0163 {
0164    constexpr float factorials[] = {
0165       1.0F,
0166       1.0F,
0167       2.0F,
0168       6.0F,
0169       24.0F,
0170       120.0F,
0171       720.0F,
0172       5040.0F,
0173       40320.0F,
0174       362880.0F,
0175       3628800.0F,
0176       39916800.0F,
0177       479001600.0F,
0178       6227020800.0F,
0179       87178291200.0F,
0180       1307674368000.0F,
0181       20922789888000.0F,
0182       355687428096000.0F,
0183       6402373705728000.0F,
0184       121645100408832000.0F,
0185       0.243290200817664e19F,
0186       0.5109094217170944e20F,
0187       0.112400072777760768e22F,
0188       0.2585201673888497664e23F,
0189       0.62044840173323943936e24F,
0190       0.15511210043330985984e26F,
0191       0.403291461126605635584e27F,
0192       0.10888869450418352160768e29F,
0193       0.304888344611713860501504e30F,
0194       0.8841761993739701954543616e31F,
0195       0.26525285981219105863630848e33F,
0196       0.822283865417792281772556288e34F,
0197       0.26313083693369353016721801216e36F,
0198       0.868331761881188649551819440128e37F,
0199       0.29523279903960414084761860964352e39F,
0200    };
0201 
0202    return factorials[i];
0203 }
0204 
0205 #endif
0206 
0207 template <>
0208 struct max_factorial<float>
0209 {
0210    static constexpr unsigned value = 34;
0211 };
0212 
0213 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0214 
0215 template <bool b>
0216 struct unchecked_factorial_data<double, b>
0217 {
0218 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0219    static constexpr boost::math::array<double, 171> factorials = { {
0220       1.0,
0221       1.0,
0222       2.0,
0223       6.0,
0224       24.0,
0225       120.0,
0226       720.0,
0227       5040.0,
0228       40320.0,
0229       362880.0,
0230       3628800.0,
0231       39916800.0,
0232       479001600.0,
0233       6227020800.0,
0234       87178291200.0,
0235       1307674368000.0,
0236       20922789888000.0,
0237       355687428096000.0,
0238       6402373705728000.0,
0239       121645100408832000.0,
0240       0.243290200817664e19,
0241       0.5109094217170944e20,
0242       0.112400072777760768e22,
0243       0.2585201673888497664e23,
0244       0.62044840173323943936e24,
0245       0.15511210043330985984e26,
0246       0.403291461126605635584e27,
0247       0.10888869450418352160768e29,
0248       0.304888344611713860501504e30,
0249       0.8841761993739701954543616e31,
0250       0.26525285981219105863630848e33,
0251       0.822283865417792281772556288e34,
0252       0.26313083693369353016721801216e36,
0253       0.868331761881188649551819440128e37,
0254       0.29523279903960414084761860964352e39,
0255       0.103331479663861449296666513375232e41,
0256       0.3719933267899012174679994481508352e42,
0257       0.137637530912263450463159795815809024e44,
0258       0.5230226174666011117600072241000742912e45,
0259       0.203978820811974433586402817399028973568e47,
0260       0.815915283247897734345611269596115894272e48,
0261       0.3345252661316380710817006205344075166515e50,
0262       0.1405006117752879898543142606244511569936e52,
0263       0.6041526306337383563735513206851399750726e53,
0264       0.265827157478844876804362581101461589032e55,
0265       0.1196222208654801945619631614956577150644e57,
0266       0.5502622159812088949850305428800254892962e58,
0267       0.2586232415111681806429643551536119799692e60,
0268       0.1241391559253607267086228904737337503852e62,
0269       0.6082818640342675608722521633212953768876e63,
0270       0.3041409320171337804361260816606476884438e65,
0271       0.1551118753287382280224243016469303211063e67,
0272       0.8065817517094387857166063685640376697529e68,
0273       0.427488328406002556429801375338939964969e70,
0274       0.2308436973392413804720927426830275810833e72,
0275       0.1269640335365827592596510084756651695958e74,
0276       0.7109985878048634518540456474637249497365e75,
0277       0.4052691950487721675568060190543232213498e77,
0278       0.2350561331282878571829474910515074683829e79,
0279       0.1386831185456898357379390197203894063459e81,
0280       0.8320987112741390144276341183223364380754e82,
0281       0.507580213877224798800856812176625227226e84,
0282       0.3146997326038793752565312235495076408801e86,
0283       0.1982608315404440064116146708361898137545e88,
0284       0.1268869321858841641034333893351614808029e90,
0285       0.8247650592082470666723170306785496252186e91,
0286       0.5443449390774430640037292402478427526443e93,
0287       0.3647111091818868528824985909660546442717e95,
0288       0.2480035542436830599600990418569171581047e97,
0289       0.1711224524281413113724683388812728390923e99,
0290       0.1197857166996989179607278372168909873646e101,
0291       0.8504785885678623175211676442399260102886e102,
0292       0.6123445837688608686152407038527467274078e104,
0293       0.4470115461512684340891257138125051110077e106,
0294       0.3307885441519386412259530282212537821457e108,
0295       0.2480914081139539809194647711659403366093e110,
0296       0.188549470166605025498793226086114655823e112,
0297       0.1451830920282858696340707840863082849837e114,
0298       0.1132428117820629783145752115873204622873e116,
0299       0.8946182130782975286851441715398316520698e117,
0300       0.7156945704626380229481153372318653216558e119,
0301       0.5797126020747367985879734231578109105412e121,
0302       0.4753643337012841748421382069894049466438e123,
0303       0.3945523969720658651189747118012061057144e125,
0304       0.3314240134565353266999387579130131288001e127,
0305       0.2817104114380550276949479442260611594801e129,
0306       0.2422709538367273238176552320344125971528e131,
0307       0.210775729837952771721360051869938959523e133,
0308       0.1854826422573984391147968456455462843802e135,
0309       0.1650795516090846108121691926245361930984e137,
0310       0.1485715964481761497309522733620825737886e139,
0311       0.1352001527678402962551665687594951421476e141,
0312       0.1243841405464130725547532432587355307758e143,
0313       0.1156772507081641574759205162306240436215e145,
0314       0.1087366156656743080273652852567866010042e147,
0315       0.103299784882390592625997020993947270954e149,
0316       0.9916779348709496892095714015418938011582e150,
0317       0.9619275968248211985332842594956369871234e152,
0318       0.942689044888324774562618574305724247381e154,
0319       0.9332621544394415268169923885626670049072e156,
0320       0.9332621544394415268169923885626670049072e158,
0321       0.9425947759838359420851623124482936749562e160,
0322       0.9614466715035126609268655586972595484554e162,
0323       0.990290071648618040754671525458177334909e164,
0324       0.1029901674514562762384858386476504428305e167,
0325       0.1081396758240290900504101305800329649721e169,
0326       0.1146280563734708354534347384148349428704e171,
0327       0.1226520203196137939351751701038733888713e173,
0328       0.132464181945182897449989183712183259981e175,
0329       0.1443859583202493582204882102462797533793e177,
0330       0.1588245541522742940425370312709077287172e179,
0331       0.1762952551090244663872161047107075788761e181,
0332       0.1974506857221074023536820372759924883413e183,
0333       0.2231192748659813646596607021218715118256e185,
0334       0.2543559733472187557120132004189335234812e187,
0335       0.2925093693493015690688151804817735520034e189,
0336       0.339310868445189820119825609358857320324e191,
0337       0.396993716080872089540195962949863064779e193,
0338       0.4684525849754290656574312362808384164393e195,
0339       0.5574585761207605881323431711741977155627e197,
0340       0.6689502913449127057588118054090372586753e199,
0341       0.8094298525273443739681622845449350829971e201,
0342       0.9875044200833601362411579871448208012564e203,
0343       0.1214630436702532967576624324188129585545e206,
0344       0.1506141741511140879795014161993280686076e208,
0345       0.1882677176888926099743767702491600857595e210,
0346       0.237217324288004688567714730513941708057e212,
0347       0.3012660018457659544809977077527059692324e214,
0348       0.3856204823625804217356770659234636406175e216,
0349       0.4974504222477287440390234150412680963966e218,
0350       0.6466855489220473672507304395536485253155e220,
0351       0.8471580690878820510984568758152795681634e222,
0352       0.1118248651196004307449963076076169029976e225,
0353       0.1487270706090685728908450891181304809868e227,
0354       0.1992942746161518876737324194182948445223e229,
0355       0.269047270731805048359538766214698040105e231,
0356       0.3659042881952548657689727220519893345429e233,
0357       0.5012888748274991661034926292112253883237e235,
0358       0.6917786472619488492228198283114910358867e237,
0359       0.9615723196941089004197195613529725398826e239,
0360       0.1346201247571752460587607385894161555836e242,
0361       0.1898143759076170969428526414110767793728e244,
0362       0.2695364137888162776588507508037290267094e246,
0363       0.3854370717180072770521565736493325081944e248,
0364       0.5550293832739304789551054660550388118e250,
0365       0.80479260574719919448490292577980627711e252,
0366       0.1174997204390910823947958271638517164581e255,
0367       0.1727245890454638911203498659308620231933e257,
0368       0.2556323917872865588581178015776757943262e259,
0369       0.380892263763056972698595524350736933546e261,
0370       0.571338395644585459047893286526105400319e263,
0371       0.8627209774233240431623188626544191544816e265,
0372       0.1311335885683452545606724671234717114812e268,
0373       0.2006343905095682394778288746989117185662e270,
0374       0.308976961384735088795856467036324046592e272,
0375       0.4789142901463393876335775239063022722176e274,
0376       0.7471062926282894447083809372938315446595e276,
0377       0.1172956879426414428192158071551315525115e279,
0378       0.1853271869493734796543609753051078529682e281,
0379       0.2946702272495038326504339507351214862195e283,
0380       0.4714723635992061322406943211761943779512e285,
0381       0.7590705053947218729075178570936729485014e287,
0382       0.1229694218739449434110178928491750176572e290,
0383       0.2004401576545302577599591653441552787813e292,
0384       0.3287218585534296227263330311644146572013e294,
0385       0.5423910666131588774984495014212841843822e296,
0386       0.9003691705778437366474261723593317460744e298,
0387       0.1503616514864999040201201707840084015944e301,
0388       0.2526075744973198387538018869171341146786e303,
0389       0.4269068009004705274939251888899566538069e305,
0390       0.7257415615307998967396728211129263114717e307,
0391    }};
0392 #else
0393    static const boost::math::array<double, 171> factorials;
0394 #endif
0395 };
0396 
0397 template <bool b>
0398 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0399    constexpr boost::math::array<double, 171> unchecked_factorial_data<double, b>::factorials;
0400 #else
0401    const boost::math::array<double, 171> unchecked_factorial_data<double, b>::factorials = {{
0402       1.0,
0403       1.0,
0404       2.0,
0405       6.0,
0406       24.0,
0407       120.0,
0408       720.0,
0409       5040.0,
0410       40320.0,
0411       362880.0,
0412       3628800.0,
0413       39916800.0,
0414       479001600.0,
0415       6227020800.0,
0416       87178291200.0,
0417       1307674368000.0,
0418       20922789888000.0,
0419       355687428096000.0,
0420       6402373705728000.0,
0421       121645100408832000.0,
0422       0.243290200817664e19,
0423       0.5109094217170944e20,
0424       0.112400072777760768e22,
0425       0.2585201673888497664e23,
0426       0.62044840173323943936e24,
0427       0.15511210043330985984e26,
0428       0.403291461126605635584e27,
0429       0.10888869450418352160768e29,
0430       0.304888344611713860501504e30,
0431       0.8841761993739701954543616e31,
0432       0.26525285981219105863630848e33,
0433       0.822283865417792281772556288e34,
0434       0.26313083693369353016721801216e36,
0435       0.868331761881188649551819440128e37,
0436       0.29523279903960414084761860964352e39,
0437       0.103331479663861449296666513375232e41,
0438       0.3719933267899012174679994481508352e42,
0439       0.137637530912263450463159795815809024e44,
0440       0.5230226174666011117600072241000742912e45,
0441       0.203978820811974433586402817399028973568e47,
0442       0.815915283247897734345611269596115894272e48,
0443       0.3345252661316380710817006205344075166515e50,
0444       0.1405006117752879898543142606244511569936e52,
0445       0.6041526306337383563735513206851399750726e53,
0446       0.265827157478844876804362581101461589032e55,
0447       0.1196222208654801945619631614956577150644e57,
0448       0.5502622159812088949850305428800254892962e58,
0449       0.2586232415111681806429643551536119799692e60,
0450       0.1241391559253607267086228904737337503852e62,
0451       0.6082818640342675608722521633212953768876e63,
0452       0.3041409320171337804361260816606476884438e65,
0453       0.1551118753287382280224243016469303211063e67,
0454       0.8065817517094387857166063685640376697529e68,
0455       0.427488328406002556429801375338939964969e70,
0456       0.2308436973392413804720927426830275810833e72,
0457       0.1269640335365827592596510084756651695958e74,
0458       0.7109985878048634518540456474637249497365e75,
0459       0.4052691950487721675568060190543232213498e77,
0460       0.2350561331282878571829474910515074683829e79,
0461       0.1386831185456898357379390197203894063459e81,
0462       0.8320987112741390144276341183223364380754e82,
0463       0.507580213877224798800856812176625227226e84,
0464       0.3146997326038793752565312235495076408801e86,
0465       0.1982608315404440064116146708361898137545e88,
0466       0.1268869321858841641034333893351614808029e90,
0467       0.8247650592082470666723170306785496252186e91,
0468       0.5443449390774430640037292402478427526443e93,
0469       0.3647111091818868528824985909660546442717e95,
0470       0.2480035542436830599600990418569171581047e97,
0471       0.1711224524281413113724683388812728390923e99,
0472       0.1197857166996989179607278372168909873646e101,
0473       0.8504785885678623175211676442399260102886e102,
0474       0.6123445837688608686152407038527467274078e104,
0475       0.4470115461512684340891257138125051110077e106,
0476       0.3307885441519386412259530282212537821457e108,
0477       0.2480914081139539809194647711659403366093e110,
0478       0.188549470166605025498793226086114655823e112,
0479       0.1451830920282858696340707840863082849837e114,
0480       0.1132428117820629783145752115873204622873e116,
0481       0.8946182130782975286851441715398316520698e117,
0482       0.7156945704626380229481153372318653216558e119,
0483       0.5797126020747367985879734231578109105412e121,
0484       0.4753643337012841748421382069894049466438e123,
0485       0.3945523969720658651189747118012061057144e125,
0486       0.3314240134565353266999387579130131288001e127,
0487       0.2817104114380550276949479442260611594801e129,
0488       0.2422709538367273238176552320344125971528e131,
0489       0.210775729837952771721360051869938959523e133,
0490       0.1854826422573984391147968456455462843802e135,
0491       0.1650795516090846108121691926245361930984e137,
0492       0.1485715964481761497309522733620825737886e139,
0493       0.1352001527678402962551665687594951421476e141,
0494       0.1243841405464130725547532432587355307758e143,
0495       0.1156772507081641574759205162306240436215e145,
0496       0.1087366156656743080273652852567866010042e147,
0497       0.103299784882390592625997020993947270954e149,
0498       0.9916779348709496892095714015418938011582e150,
0499       0.9619275968248211985332842594956369871234e152,
0500       0.942689044888324774562618574305724247381e154,
0501       0.9332621544394415268169923885626670049072e156,
0502       0.9332621544394415268169923885626670049072e158,
0503       0.9425947759838359420851623124482936749562e160,
0504       0.9614466715035126609268655586972595484554e162,
0505       0.990290071648618040754671525458177334909e164,
0506       0.1029901674514562762384858386476504428305e167,
0507       0.1081396758240290900504101305800329649721e169,
0508       0.1146280563734708354534347384148349428704e171,
0509       0.1226520203196137939351751701038733888713e173,
0510       0.132464181945182897449989183712183259981e175,
0511       0.1443859583202493582204882102462797533793e177,
0512       0.1588245541522742940425370312709077287172e179,
0513       0.1762952551090244663872161047107075788761e181,
0514       0.1974506857221074023536820372759924883413e183,
0515       0.2231192748659813646596607021218715118256e185,
0516       0.2543559733472187557120132004189335234812e187,
0517       0.2925093693493015690688151804817735520034e189,
0518       0.339310868445189820119825609358857320324e191,
0519       0.396993716080872089540195962949863064779e193,
0520       0.4684525849754290656574312362808384164393e195,
0521       0.5574585761207605881323431711741977155627e197,
0522       0.6689502913449127057588118054090372586753e199,
0523       0.8094298525273443739681622845449350829971e201,
0524       0.9875044200833601362411579871448208012564e203,
0525       0.1214630436702532967576624324188129585545e206,
0526       0.1506141741511140879795014161993280686076e208,
0527       0.1882677176888926099743767702491600857595e210,
0528       0.237217324288004688567714730513941708057e212,
0529       0.3012660018457659544809977077527059692324e214,
0530       0.3856204823625804217356770659234636406175e216,
0531       0.4974504222477287440390234150412680963966e218,
0532       0.6466855489220473672507304395536485253155e220,
0533       0.8471580690878820510984568758152795681634e222,
0534       0.1118248651196004307449963076076169029976e225,
0535       0.1487270706090685728908450891181304809868e227,
0536       0.1992942746161518876737324194182948445223e229,
0537       0.269047270731805048359538766214698040105e231,
0538       0.3659042881952548657689727220519893345429e233,
0539       0.5012888748274991661034926292112253883237e235,
0540       0.6917786472619488492228198283114910358867e237,
0541       0.9615723196941089004197195613529725398826e239,
0542       0.1346201247571752460587607385894161555836e242,
0543       0.1898143759076170969428526414110767793728e244,
0544       0.2695364137888162776588507508037290267094e246,
0545       0.3854370717180072770521565736493325081944e248,
0546       0.5550293832739304789551054660550388118e250,
0547       0.80479260574719919448490292577980627711e252,
0548       0.1174997204390910823947958271638517164581e255,
0549       0.1727245890454638911203498659308620231933e257,
0550       0.2556323917872865588581178015776757943262e259,
0551       0.380892263763056972698595524350736933546e261,
0552       0.571338395644585459047893286526105400319e263,
0553       0.8627209774233240431623188626544191544816e265,
0554       0.1311335885683452545606724671234717114812e268,
0555       0.2006343905095682394778288746989117185662e270,
0556       0.308976961384735088795856467036324046592e272,
0557       0.4789142901463393876335775239063022722176e274,
0558       0.7471062926282894447083809372938315446595e276,
0559       0.1172956879426414428192158071551315525115e279,
0560       0.1853271869493734796543609753051078529682e281,
0561       0.2946702272495038326504339507351214862195e283,
0562       0.4714723635992061322406943211761943779512e285,
0563       0.7590705053947218729075178570936729485014e287,
0564       0.1229694218739449434110178928491750176572e290,
0565       0.2004401576545302577599591653441552787813e292,
0566       0.3287218585534296227263330311644146572013e294,
0567       0.5423910666131588774984495014212841843822e296,
0568       0.9003691705778437366474261723593317460744e298,
0569       0.1503616514864999040201201707840084015944e301,
0570       0.2526075744973198387538018869171341146786e303,
0571       0.4269068009004705274939251888899566538069e305,
0572       0.7257415615307998967396728211129263114717e307,
0573    }};
0574 #endif
0575 
0576 template <>
0577 BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial<double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
0578 {
0579    return unchecked_factorial_data<double>::factorials[i];
0580 }
0581 
0582 template <>
0583 struct max_factorial<double>
0584 {
0585    static constexpr unsigned value = 170;
0586 };
0587 
0588 #else
0589 
0590 template <>
0591 BOOST_MATH_GPU_ENABLED inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial<double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
0592 {
0593    constexpr double factorials[] = {
0594       1,
0595       1,
0596       2,
0597       6,
0598       24,
0599       120,
0600       720,
0601       5040,
0602       40320,
0603       362880.0,
0604       3628800.0,
0605       39916800.0,
0606       479001600.0,
0607       6227020800.0,
0608       87178291200.0,
0609       1307674368000.0,
0610       20922789888000.0,
0611       355687428096000.0,
0612       6402373705728000.0,
0613       121645100408832000.0,
0614       0.243290200817664e19,
0615       0.5109094217170944e20,
0616       0.112400072777760768e22,
0617       0.2585201673888497664e23,
0618       0.62044840173323943936e24,
0619       0.15511210043330985984e26,
0620       0.403291461126605635584e27,
0621       0.10888869450418352160768e29,
0622       0.304888344611713860501504e30,
0623       0.8841761993739701954543616e31,
0624       0.26525285981219105863630848e33,
0625       0.822283865417792281772556288e34,
0626       0.26313083693369353016721801216e36,
0627       0.868331761881188649551819440128e37,
0628       0.29523279903960414084761860964352e39,
0629    };
0630 
0631    return factorials[i];
0632 }
0633 
0634 template <>
0635 struct max_factorial<double>
0636 {
0637    static constexpr unsigned value = 34;
0638 };
0639 
0640 #endif
0641 
0642 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
0643 
0644 template <bool b>
0645 struct unchecked_factorial_data<long double, b>
0646 {
0647 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0648    static constexpr boost::math::array<long double, 171> factorials = { {
0649       1L,
0650       1L,
0651       2L,
0652       6L,
0653       24L,
0654       120L,
0655       720L,
0656       5040L,
0657       40320L,
0658       362880.0L,
0659       3628800.0L,
0660       39916800.0L,
0661       479001600.0L,
0662       6227020800.0L,
0663       87178291200.0L,
0664       1307674368000.0L,
0665       20922789888000.0L,
0666       355687428096000.0L,
0667       6402373705728000.0L,
0668       121645100408832000.0L,
0669       0.243290200817664e19L,
0670       0.5109094217170944e20L,
0671       0.112400072777760768e22L,
0672       0.2585201673888497664e23L,
0673       0.62044840173323943936e24L,
0674       0.15511210043330985984e26L,
0675       0.403291461126605635584e27L,
0676       0.10888869450418352160768e29L,
0677       0.304888344611713860501504e30L,
0678       0.8841761993739701954543616e31L,
0679       0.26525285981219105863630848e33L,
0680       0.822283865417792281772556288e34L,
0681       0.26313083693369353016721801216e36L,
0682       0.868331761881188649551819440128e37L,
0683       0.29523279903960414084761860964352e39L,
0684       0.103331479663861449296666513375232e41L,
0685       0.3719933267899012174679994481508352e42L,
0686       0.137637530912263450463159795815809024e44L,
0687       0.5230226174666011117600072241000742912e45L,
0688       0.203978820811974433586402817399028973568e47L,
0689       0.815915283247897734345611269596115894272e48L,
0690       0.3345252661316380710817006205344075166515e50L,
0691       0.1405006117752879898543142606244511569936e52L,
0692       0.6041526306337383563735513206851399750726e53L,
0693       0.265827157478844876804362581101461589032e55L,
0694       0.1196222208654801945619631614956577150644e57L,
0695       0.5502622159812088949850305428800254892962e58L,
0696       0.2586232415111681806429643551536119799692e60L,
0697       0.1241391559253607267086228904737337503852e62L,
0698       0.6082818640342675608722521633212953768876e63L,
0699       0.3041409320171337804361260816606476884438e65L,
0700       0.1551118753287382280224243016469303211063e67L,
0701       0.8065817517094387857166063685640376697529e68L,
0702       0.427488328406002556429801375338939964969e70L,
0703       0.2308436973392413804720927426830275810833e72L,
0704       0.1269640335365827592596510084756651695958e74L,
0705       0.7109985878048634518540456474637249497365e75L,
0706       0.4052691950487721675568060190543232213498e77L,
0707       0.2350561331282878571829474910515074683829e79L,
0708       0.1386831185456898357379390197203894063459e81L,
0709       0.8320987112741390144276341183223364380754e82L,
0710       0.507580213877224798800856812176625227226e84L,
0711       0.3146997326038793752565312235495076408801e86L,
0712       0.1982608315404440064116146708361898137545e88L,
0713       0.1268869321858841641034333893351614808029e90L,
0714       0.8247650592082470666723170306785496252186e91L,
0715       0.5443449390774430640037292402478427526443e93L,
0716       0.3647111091818868528824985909660546442717e95L,
0717       0.2480035542436830599600990418569171581047e97L,
0718       0.1711224524281413113724683388812728390923e99L,
0719       0.1197857166996989179607278372168909873646e101L,
0720       0.8504785885678623175211676442399260102886e102L,
0721       0.6123445837688608686152407038527467274078e104L,
0722       0.4470115461512684340891257138125051110077e106L,
0723       0.3307885441519386412259530282212537821457e108L,
0724       0.2480914081139539809194647711659403366093e110L,
0725       0.188549470166605025498793226086114655823e112L,
0726       0.1451830920282858696340707840863082849837e114L,
0727       0.1132428117820629783145752115873204622873e116L,
0728       0.8946182130782975286851441715398316520698e117L,
0729       0.7156945704626380229481153372318653216558e119L,
0730       0.5797126020747367985879734231578109105412e121L,
0731       0.4753643337012841748421382069894049466438e123L,
0732       0.3945523969720658651189747118012061057144e125L,
0733       0.3314240134565353266999387579130131288001e127L,
0734       0.2817104114380550276949479442260611594801e129L,
0735       0.2422709538367273238176552320344125971528e131L,
0736       0.210775729837952771721360051869938959523e133L,
0737       0.1854826422573984391147968456455462843802e135L,
0738       0.1650795516090846108121691926245361930984e137L,
0739       0.1485715964481761497309522733620825737886e139L,
0740       0.1352001527678402962551665687594951421476e141L,
0741       0.1243841405464130725547532432587355307758e143L,
0742       0.1156772507081641574759205162306240436215e145L,
0743       0.1087366156656743080273652852567866010042e147L,
0744       0.103299784882390592625997020993947270954e149L,
0745       0.9916779348709496892095714015418938011582e150L,
0746       0.9619275968248211985332842594956369871234e152L,
0747       0.942689044888324774562618574305724247381e154L,
0748       0.9332621544394415268169923885626670049072e156L,
0749       0.9332621544394415268169923885626670049072e158L,
0750       0.9425947759838359420851623124482936749562e160L,
0751       0.9614466715035126609268655586972595484554e162L,
0752       0.990290071648618040754671525458177334909e164L,
0753       0.1029901674514562762384858386476504428305e167L,
0754       0.1081396758240290900504101305800329649721e169L,
0755       0.1146280563734708354534347384148349428704e171L,
0756       0.1226520203196137939351751701038733888713e173L,
0757       0.132464181945182897449989183712183259981e175L,
0758       0.1443859583202493582204882102462797533793e177L,
0759       0.1588245541522742940425370312709077287172e179L,
0760       0.1762952551090244663872161047107075788761e181L,
0761       0.1974506857221074023536820372759924883413e183L,
0762       0.2231192748659813646596607021218715118256e185L,
0763       0.2543559733472187557120132004189335234812e187L,
0764       0.2925093693493015690688151804817735520034e189L,
0765       0.339310868445189820119825609358857320324e191L,
0766       0.396993716080872089540195962949863064779e193L,
0767       0.4684525849754290656574312362808384164393e195L,
0768       0.5574585761207605881323431711741977155627e197L,
0769       0.6689502913449127057588118054090372586753e199L,
0770       0.8094298525273443739681622845449350829971e201L,
0771       0.9875044200833601362411579871448208012564e203L,
0772       0.1214630436702532967576624324188129585545e206L,
0773       0.1506141741511140879795014161993280686076e208L,
0774       0.1882677176888926099743767702491600857595e210L,
0775       0.237217324288004688567714730513941708057e212L,
0776       0.3012660018457659544809977077527059692324e214L,
0777       0.3856204823625804217356770659234636406175e216L,
0778       0.4974504222477287440390234150412680963966e218L,
0779       0.6466855489220473672507304395536485253155e220L,
0780       0.8471580690878820510984568758152795681634e222L,
0781       0.1118248651196004307449963076076169029976e225L,
0782       0.1487270706090685728908450891181304809868e227L,
0783       0.1992942746161518876737324194182948445223e229L,
0784       0.269047270731805048359538766214698040105e231L,
0785       0.3659042881952548657689727220519893345429e233L,
0786       0.5012888748274991661034926292112253883237e235L,
0787       0.6917786472619488492228198283114910358867e237L,
0788       0.9615723196941089004197195613529725398826e239L,
0789       0.1346201247571752460587607385894161555836e242L,
0790       0.1898143759076170969428526414110767793728e244L,
0791       0.2695364137888162776588507508037290267094e246L,
0792       0.3854370717180072770521565736493325081944e248L,
0793       0.5550293832739304789551054660550388118e250L,
0794       0.80479260574719919448490292577980627711e252L,
0795       0.1174997204390910823947958271638517164581e255L,
0796       0.1727245890454638911203498659308620231933e257L,
0797       0.2556323917872865588581178015776757943262e259L,
0798       0.380892263763056972698595524350736933546e261L,
0799       0.571338395644585459047893286526105400319e263L,
0800       0.8627209774233240431623188626544191544816e265L,
0801       0.1311335885683452545606724671234717114812e268L,
0802       0.2006343905095682394778288746989117185662e270L,
0803       0.308976961384735088795856467036324046592e272L,
0804       0.4789142901463393876335775239063022722176e274L,
0805       0.7471062926282894447083809372938315446595e276L,
0806       0.1172956879426414428192158071551315525115e279L,
0807       0.1853271869493734796543609753051078529682e281L,
0808       0.2946702272495038326504339507351214862195e283L,
0809       0.4714723635992061322406943211761943779512e285L,
0810       0.7590705053947218729075178570936729485014e287L,
0811       0.1229694218739449434110178928491750176572e290L,
0812       0.2004401576545302577599591653441552787813e292L,
0813       0.3287218585534296227263330311644146572013e294L,
0814       0.5423910666131588774984495014212841843822e296L,
0815       0.9003691705778437366474261723593317460744e298L,
0816       0.1503616514864999040201201707840084015944e301L,
0817       0.2526075744973198387538018869171341146786e303L,
0818       0.4269068009004705274939251888899566538069e305L,
0819       0.7257415615307998967396728211129263114717e307L,
0820    }};
0821 #else
0822    static const boost::math::array<long double, 171> factorials;
0823 #endif
0824 };
0825 
0826 template <bool b>
0827 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
0828    constexpr boost::math::array<long double, 171> unchecked_factorial_data<long double, b>::factorials;
0829 #else
0830    const boost::math::array<long double, 171> unchecked_factorial_data<long double, b>::factorials = {{
0831       1L,
0832       1L,
0833       2L,
0834       6L,
0835       24L,
0836       120L,
0837       720L,
0838       5040L,
0839       40320L,
0840       362880.0L,
0841       3628800.0L,
0842       39916800.0L,
0843       479001600.0L,
0844       6227020800.0L,
0845       87178291200.0L,
0846       1307674368000.0L,
0847       20922789888000.0L,
0848       355687428096000.0L,
0849       6402373705728000.0L,
0850       121645100408832000.0L,
0851       0.243290200817664e19L,
0852       0.5109094217170944e20L,
0853       0.112400072777760768e22L,
0854       0.2585201673888497664e23L,
0855       0.62044840173323943936e24L,
0856       0.15511210043330985984e26L,
0857       0.403291461126605635584e27L,
0858       0.10888869450418352160768e29L,
0859       0.304888344611713860501504e30L,
0860       0.8841761993739701954543616e31L,
0861       0.26525285981219105863630848e33L,
0862       0.822283865417792281772556288e34L,
0863       0.26313083693369353016721801216e36L,
0864       0.868331761881188649551819440128e37L,
0865       0.29523279903960414084761860964352e39L,
0866       0.103331479663861449296666513375232e41L,
0867       0.3719933267899012174679994481508352e42L,
0868       0.137637530912263450463159795815809024e44L,
0869       0.5230226174666011117600072241000742912e45L,
0870       0.203978820811974433586402817399028973568e47L,
0871       0.815915283247897734345611269596115894272e48L,
0872       0.3345252661316380710817006205344075166515e50L,
0873       0.1405006117752879898543142606244511569936e52L,
0874       0.6041526306337383563735513206851399750726e53L,
0875       0.265827157478844876804362581101461589032e55L,
0876       0.1196222208654801945619631614956577150644e57L,
0877       0.5502622159812088949850305428800254892962e58L,
0878       0.2586232415111681806429643551536119799692e60L,
0879       0.1241391559253607267086228904737337503852e62L,
0880       0.6082818640342675608722521633212953768876e63L,
0881       0.3041409320171337804361260816606476884438e65L,
0882       0.1551118753287382280224243016469303211063e67L,
0883       0.8065817517094387857166063685640376697529e68L,
0884       0.427488328406002556429801375338939964969e70L,
0885       0.2308436973392413804720927426830275810833e72L,
0886       0.1269640335365827592596510084756651695958e74L,
0887       0.7109985878048634518540456474637249497365e75L,
0888       0.4052691950487721675568060190543232213498e77L,
0889       0.2350561331282878571829474910515074683829e79L,
0890       0.1386831185456898357379390197203894063459e81L,
0891       0.8320987112741390144276341183223364380754e82L,
0892       0.507580213877224798800856812176625227226e84L,
0893       0.3146997326038793752565312235495076408801e86L,
0894       0.1982608315404440064116146708361898137545e88L,
0895       0.1268869321858841641034333893351614808029e90L,
0896       0.8247650592082470666723170306785496252186e91L,
0897       0.5443449390774430640037292402478427526443e93L,
0898       0.3647111091818868528824985909660546442717e95L,
0899       0.2480035542436830599600990418569171581047e97L,
0900       0.1711224524281413113724683388812728390923e99L,
0901       0.1197857166996989179607278372168909873646e101L,
0902       0.8504785885678623175211676442399260102886e102L,
0903       0.6123445837688608686152407038527467274078e104L,
0904       0.4470115461512684340891257138125051110077e106L,
0905       0.3307885441519386412259530282212537821457e108L,
0906       0.2480914081139539809194647711659403366093e110L,
0907       0.188549470166605025498793226086114655823e112L,
0908       0.1451830920282858696340707840863082849837e114L,
0909       0.1132428117820629783145752115873204622873e116L,
0910       0.8946182130782975286851441715398316520698e117L,
0911       0.7156945704626380229481153372318653216558e119L,
0912       0.5797126020747367985879734231578109105412e121L,
0913       0.4753643337012841748421382069894049466438e123L,
0914       0.3945523969720658651189747118012061057144e125L,
0915       0.3314240134565353266999387579130131288001e127L,
0916       0.2817104114380550276949479442260611594801e129L,
0917       0.2422709538367273238176552320344125971528e131L,
0918       0.210775729837952771721360051869938959523e133L,
0919       0.1854826422573984391147968456455462843802e135L,
0920       0.1650795516090846108121691926245361930984e137L,
0921       0.1485715964481761497309522733620825737886e139L,
0922       0.1352001527678402962551665687594951421476e141L,
0923       0.1243841405464130725547532432587355307758e143L,
0924       0.1156772507081641574759205162306240436215e145L,
0925       0.1087366156656743080273652852567866010042e147L,
0926       0.103299784882390592625997020993947270954e149L,
0927       0.9916779348709496892095714015418938011582e150L,
0928       0.9619275968248211985332842594956369871234e152L,
0929       0.942689044888324774562618574305724247381e154L,
0930       0.9332621544394415268169923885626670049072e156L,
0931       0.9332621544394415268169923885626670049072e158L,
0932       0.9425947759838359420851623124482936749562e160L,
0933       0.9614466715035126609268655586972595484554e162L,
0934       0.990290071648618040754671525458177334909e164L,
0935       0.1029901674514562762384858386476504428305e167L,
0936       0.1081396758240290900504101305800329649721e169L,
0937       0.1146280563734708354534347384148349428704e171L,
0938       0.1226520203196137939351751701038733888713e173L,
0939       0.132464181945182897449989183712183259981e175L,
0940       0.1443859583202493582204882102462797533793e177L,
0941       0.1588245541522742940425370312709077287172e179L,
0942       0.1762952551090244663872161047107075788761e181L,
0943       0.1974506857221074023536820372759924883413e183L,
0944       0.2231192748659813646596607021218715118256e185L,
0945       0.2543559733472187557120132004189335234812e187L,
0946       0.2925093693493015690688151804817735520034e189L,
0947       0.339310868445189820119825609358857320324e191L,
0948       0.396993716080872089540195962949863064779e193L,
0949       0.4684525849754290656574312362808384164393e195L,
0950       0.5574585761207605881323431711741977155627e197L,
0951       0.6689502913449127057588118054090372586753e199L,
0952       0.8094298525273443739681622845449350829971e201L,
0953       0.9875044200833601362411579871448208012564e203L,
0954       0.1214630436702532967576624324188129585545e206L,
0955       0.1506141741511140879795014161993280686076e208L,
0956       0.1882677176888926099743767702491600857595e210L,
0957       0.237217324288004688567714730513941708057e212L,
0958       0.3012660018457659544809977077527059692324e214L,
0959       0.3856204823625804217356770659234636406175e216L,
0960       0.4974504222477287440390234150412680963966e218L,
0961       0.6466855489220473672507304395536485253155e220L,
0962       0.8471580690878820510984568758152795681634e222L,
0963       0.1118248651196004307449963076076169029976e225L,
0964       0.1487270706090685728908450891181304809868e227L,
0965       0.1992942746161518876737324194182948445223e229L,
0966       0.269047270731805048359538766214698040105e231L,
0967       0.3659042881952548657689727220519893345429e233L,
0968       0.5012888748274991661034926292112253883237e235L,
0969       0.6917786472619488492228198283114910358867e237L,
0970       0.9615723196941089004197195613529725398826e239L,
0971       0.1346201247571752460587607385894161555836e242L,
0972       0.1898143759076170969428526414110767793728e244L,
0973       0.2695364137888162776588507508037290267094e246L,
0974       0.3854370717180072770521565736493325081944e248L,
0975       0.5550293832739304789551054660550388118e250L,
0976       0.80479260574719919448490292577980627711e252L,
0977       0.1174997204390910823947958271638517164581e255L,
0978       0.1727245890454638911203498659308620231933e257L,
0979       0.2556323917872865588581178015776757943262e259L,
0980       0.380892263763056972698595524350736933546e261L,
0981       0.571338395644585459047893286526105400319e263L,
0982       0.8627209774233240431623188626544191544816e265L,
0983       0.1311335885683452545606724671234717114812e268L,
0984       0.2006343905095682394778288746989117185662e270L,
0985       0.308976961384735088795856467036324046592e272L,
0986       0.4789142901463393876335775239063022722176e274L,
0987       0.7471062926282894447083809372938315446595e276L,
0988       0.1172956879426414428192158071551315525115e279L,
0989       0.1853271869493734796543609753051078529682e281L,
0990       0.2946702272495038326504339507351214862195e283L,
0991       0.4714723635992061322406943211761943779512e285L,
0992       0.7590705053947218729075178570936729485014e287L,
0993       0.1229694218739449434110178928491750176572e290L,
0994       0.2004401576545302577599591653441552787813e292L,
0995       0.3287218585534296227263330311644146572013e294L,
0996       0.5423910666131588774984495014212841843822e296L,
0997       0.9003691705778437366474261723593317460744e298L,
0998       0.1503616514864999040201201707840084015944e301L,
0999       0.2526075744973198387538018869171341146786e303L,
1000       0.4269068009004705274939251888899566538069e305L,
1001       0.7257415615307998967396728211129263114717e307L,
1002    }};
1003 #endif
1004 
1005 template <>
1006 inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION long double unchecked_factorial<long double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
1007 {
1008    return unchecked_factorial_data<long double>::factorials[i];
1009 }
1010 
1011 template <>
1012 struct max_factorial<long double>
1013 {
1014    static constexpr unsigned value = 170;
1015 };
1016 
1017 #ifdef BOOST_MATH_USE_FLOAT128
1018 
1019 template <bool b>
1020 struct unchecked_factorial_data<BOOST_MATH_FLOAT128_TYPE, b>
1021 {
1022 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
1023    static constexpr boost::math::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
1024       1,
1025       1,
1026       2,
1027       6,
1028       24,
1029       120,
1030       720,
1031       5040,
1032       40320,
1033       362880.0Q,
1034       3628800.0Q,
1035       39916800.0Q,
1036       479001600.0Q,
1037       6227020800.0Q,
1038       87178291200.0Q,
1039       1307674368000.0Q,
1040       20922789888000.0Q,
1041       355687428096000.0Q,
1042       6402373705728000.0Q,
1043       121645100408832000.0Q,
1044       0.243290200817664e19Q,
1045       0.5109094217170944e20Q,
1046       0.112400072777760768e22Q,
1047       0.2585201673888497664e23Q,
1048       0.62044840173323943936e24Q,
1049       0.15511210043330985984e26Q,
1050       0.403291461126605635584e27Q,
1051       0.10888869450418352160768e29Q,
1052       0.304888344611713860501504e30Q,
1053       0.8841761993739701954543616e31Q,
1054       0.26525285981219105863630848e33Q,
1055       0.822283865417792281772556288e34Q,
1056       0.26313083693369353016721801216e36Q,
1057       0.868331761881188649551819440128e37Q,
1058       0.29523279903960414084761860964352e39Q,
1059       0.103331479663861449296666513375232e41Q,
1060       0.3719933267899012174679994481508352e42Q,
1061       0.137637530912263450463159795815809024e44Q,
1062       0.5230226174666011117600072241000742912e45Q,
1063       0.203978820811974433586402817399028973568e47Q,
1064       0.815915283247897734345611269596115894272e48Q,
1065       0.3345252661316380710817006205344075166515e50Q,
1066       0.1405006117752879898543142606244511569936e52Q,
1067       0.6041526306337383563735513206851399750726e53Q,
1068       0.265827157478844876804362581101461589032e55Q,
1069       0.1196222208654801945619631614956577150644e57Q,
1070       0.5502622159812088949850305428800254892962e58Q,
1071       0.2586232415111681806429643551536119799692e60Q,
1072       0.1241391559253607267086228904737337503852e62Q,
1073       0.6082818640342675608722521633212953768876e63Q,
1074       0.3041409320171337804361260816606476884438e65Q,
1075       0.1551118753287382280224243016469303211063e67Q,
1076       0.8065817517094387857166063685640376697529e68Q,
1077       0.427488328406002556429801375338939964969e70Q,
1078       0.2308436973392413804720927426830275810833e72Q,
1079       0.1269640335365827592596510084756651695958e74Q,
1080       0.7109985878048634518540456474637249497365e75Q,
1081       0.4052691950487721675568060190543232213498e77Q,
1082       0.2350561331282878571829474910515074683829e79Q,
1083       0.1386831185456898357379390197203894063459e81Q,
1084       0.8320987112741390144276341183223364380754e82Q,
1085       0.507580213877224798800856812176625227226e84Q,
1086       0.3146997326038793752565312235495076408801e86Q,
1087       0.1982608315404440064116146708361898137545e88Q,
1088       0.1268869321858841641034333893351614808029e90Q,
1089       0.8247650592082470666723170306785496252186e91Q,
1090       0.5443449390774430640037292402478427526443e93Q,
1091       0.3647111091818868528824985909660546442717e95Q,
1092       0.2480035542436830599600990418569171581047e97Q,
1093       0.1711224524281413113724683388812728390923e99Q,
1094       0.1197857166996989179607278372168909873646e101Q,
1095       0.8504785885678623175211676442399260102886e102Q,
1096       0.6123445837688608686152407038527467274078e104Q,
1097       0.4470115461512684340891257138125051110077e106Q,
1098       0.3307885441519386412259530282212537821457e108Q,
1099       0.2480914081139539809194647711659403366093e110Q,
1100       0.188549470166605025498793226086114655823e112Q,
1101       0.1451830920282858696340707840863082849837e114Q,
1102       0.1132428117820629783145752115873204622873e116Q,
1103       0.8946182130782975286851441715398316520698e117Q,
1104       0.7156945704626380229481153372318653216558e119Q,
1105       0.5797126020747367985879734231578109105412e121Q,
1106       0.4753643337012841748421382069894049466438e123Q,
1107       0.3945523969720658651189747118012061057144e125Q,
1108       0.3314240134565353266999387579130131288001e127Q,
1109       0.2817104114380550276949479442260611594801e129Q,
1110       0.2422709538367273238176552320344125971528e131Q,
1111       0.210775729837952771721360051869938959523e133Q,
1112       0.1854826422573984391147968456455462843802e135Q,
1113       0.1650795516090846108121691926245361930984e137Q,
1114       0.1485715964481761497309522733620825737886e139Q,
1115       0.1352001527678402962551665687594951421476e141Q,
1116       0.1243841405464130725547532432587355307758e143Q,
1117       0.1156772507081641574759205162306240436215e145Q,
1118       0.1087366156656743080273652852567866010042e147Q,
1119       0.103299784882390592625997020993947270954e149Q,
1120       0.9916779348709496892095714015418938011582e150Q,
1121       0.9619275968248211985332842594956369871234e152Q,
1122       0.942689044888324774562618574305724247381e154Q,
1123       0.9332621544394415268169923885626670049072e156Q,
1124       0.9332621544394415268169923885626670049072e158Q,
1125       0.9425947759838359420851623124482936749562e160Q,
1126       0.9614466715035126609268655586972595484554e162Q,
1127       0.990290071648618040754671525458177334909e164Q,
1128       0.1029901674514562762384858386476504428305e167Q,
1129       0.1081396758240290900504101305800329649721e169Q,
1130       0.1146280563734708354534347384148349428704e171Q,
1131       0.1226520203196137939351751701038733888713e173Q,
1132       0.132464181945182897449989183712183259981e175Q,
1133       0.1443859583202493582204882102462797533793e177Q,
1134       0.1588245541522742940425370312709077287172e179Q,
1135       0.1762952551090244663872161047107075788761e181Q,
1136       0.1974506857221074023536820372759924883413e183Q,
1137       0.2231192748659813646596607021218715118256e185Q,
1138       0.2543559733472187557120132004189335234812e187Q,
1139       0.2925093693493015690688151804817735520034e189Q,
1140       0.339310868445189820119825609358857320324e191Q,
1141       0.396993716080872089540195962949863064779e193Q,
1142       0.4684525849754290656574312362808384164393e195Q,
1143       0.5574585761207605881323431711741977155627e197Q,
1144       0.6689502913449127057588118054090372586753e199Q,
1145       0.8094298525273443739681622845449350829971e201Q,
1146       0.9875044200833601362411579871448208012564e203Q,
1147       0.1214630436702532967576624324188129585545e206Q,
1148       0.1506141741511140879795014161993280686076e208Q,
1149       0.1882677176888926099743767702491600857595e210Q,
1150       0.237217324288004688567714730513941708057e212Q,
1151       0.3012660018457659544809977077527059692324e214Q,
1152       0.3856204823625804217356770659234636406175e216Q,
1153       0.4974504222477287440390234150412680963966e218Q,
1154       0.6466855489220473672507304395536485253155e220Q,
1155       0.8471580690878820510984568758152795681634e222Q,
1156       0.1118248651196004307449963076076169029976e225Q,
1157       0.1487270706090685728908450891181304809868e227Q,
1158       0.1992942746161518876737324194182948445223e229Q,
1159       0.269047270731805048359538766214698040105e231Q,
1160       0.3659042881952548657689727220519893345429e233Q,
1161       0.5012888748274991661034926292112253883237e235Q,
1162       0.6917786472619488492228198283114910358867e237Q,
1163       0.9615723196941089004197195613529725398826e239Q,
1164       0.1346201247571752460587607385894161555836e242Q,
1165       0.1898143759076170969428526414110767793728e244Q,
1166       0.2695364137888162776588507508037290267094e246Q,
1167       0.3854370717180072770521565736493325081944e248Q,
1168       0.5550293832739304789551054660550388118e250Q,
1169       0.80479260574719919448490292577980627711e252Q,
1170       0.1174997204390910823947958271638517164581e255Q,
1171       0.1727245890454638911203498659308620231933e257Q,
1172       0.2556323917872865588581178015776757943262e259Q,
1173       0.380892263763056972698595524350736933546e261Q,
1174       0.571338395644585459047893286526105400319e263Q,
1175       0.8627209774233240431623188626544191544816e265Q,
1176       0.1311335885683452545606724671234717114812e268Q,
1177       0.2006343905095682394778288746989117185662e270Q,
1178       0.308976961384735088795856467036324046592e272Q,
1179       0.4789142901463393876335775239063022722176e274Q,
1180       0.7471062926282894447083809372938315446595e276Q,
1181       0.1172956879426414428192158071551315525115e279Q,
1182       0.1853271869493734796543609753051078529682e281Q,
1183       0.2946702272495038326504339507351214862195e283Q,
1184       0.4714723635992061322406943211761943779512e285Q,
1185       0.7590705053947218729075178570936729485014e287Q,
1186       0.1229694218739449434110178928491750176572e290Q,
1187       0.2004401576545302577599591653441552787813e292Q,
1188       0.3287218585534296227263330311644146572013e294Q,
1189       0.5423910666131588774984495014212841843822e296Q,
1190       0.9003691705778437366474261723593317460744e298Q,
1191       0.1503616514864999040201201707840084015944e301Q,
1192       0.2526075744973198387538018869171341146786e303Q,
1193       0.4269068009004705274939251888899566538069e305Q,
1194       0.7257415615307998967396728211129263114717e307Q,
1195    } };
1196 #else
1197    static const boost::math::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials;
1198 #endif
1199 };
1200 
1201 template <bool b>
1202 #ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
1203 constexpr boost::math::array<BOOST_MATH_FLOAT128_TYPE, 171> unchecked_factorial_data<BOOST_MATH_FLOAT128_TYPE, b>::factorials;
1204 #else
1205 const boost::math::array<BOOST_MATH_FLOAT128_TYPE, 171> unchecked_factorial_data<BOOST_MATH_FLOAT128_TYPE, b>::factorials = { {
1206       1,
1207       1,
1208       2,
1209       6,
1210       24,
1211       120,
1212       720,
1213       5040,
1214       40320,
1215       362880.0Q,
1216       3628800.0Q,
1217       39916800.0Q,
1218       479001600.0Q,
1219       6227020800.0Q,
1220       87178291200.0Q,
1221       1307674368000.0Q,
1222       20922789888000.0Q,
1223       355687428096000.0Q,
1224       6402373705728000.0Q,
1225       121645100408832000.0Q,
1226       0.243290200817664e19Q,
1227       0.5109094217170944e20Q,
1228       0.112400072777760768e22Q,
1229       0.2585201673888497664e23Q,
1230       0.62044840173323943936e24Q,
1231       0.15511210043330985984e26Q,
1232       0.403291461126605635584e27Q,
1233       0.10888869450418352160768e29Q,
1234       0.304888344611713860501504e30Q,
1235       0.8841761993739701954543616e31Q,
1236       0.26525285981219105863630848e33Q,
1237       0.822283865417792281772556288e34Q,
1238       0.26313083693369353016721801216e36Q,
1239       0.868331761881188649551819440128e37Q,
1240       0.29523279903960414084761860964352e39Q,
1241       0.103331479663861449296666513375232e41Q,
1242       0.3719933267899012174679994481508352e42Q,
1243       0.137637530912263450463159795815809024e44Q,
1244       0.5230226174666011117600072241000742912e45Q,
1245       0.203978820811974433586402817399028973568e47Q,
1246       0.815915283247897734345611269596115894272e48Q,
1247       0.3345252661316380710817006205344075166515e50Q,
1248       0.1405006117752879898543142606244511569936e52Q,
1249       0.6041526306337383563735513206851399750726e53Q,
1250       0.265827157478844876804362581101461589032e55Q,
1251       0.1196222208654801945619631614956577150644e57Q,
1252       0.5502622159812088949850305428800254892962e58Q,
1253       0.2586232415111681806429643551536119799692e60Q,
1254       0.1241391559253607267086228904737337503852e62Q,
1255       0.6082818640342675608722521633212953768876e63Q,
1256       0.3041409320171337804361260816606476884438e65Q,
1257       0.1551118753287382280224243016469303211063e67Q,
1258       0.8065817517094387857166063685640376697529e68Q,
1259       0.427488328406002556429801375338939964969e70Q,
1260       0.2308436973392413804720927426830275810833e72Q,
1261       0.1269640335365827592596510084756651695958e74Q,
1262       0.7109985878048634518540456474637249497365e75Q,
1263       0.4052691950487721675568060190543232213498e77Q,
1264       0.2350561331282878571829474910515074683829e79Q,
1265       0.1386831185456898357379390197203894063459e81Q,
1266       0.8320987112741390144276341183223364380754e82Q,
1267       0.507580213877224798800856812176625227226e84Q,
1268       0.3146997326038793752565312235495076408801e86Q,
1269       0.1982608315404440064116146708361898137545e88Q,
1270       0.1268869321858841641034333893351614808029e90Q,
1271       0.8247650592082470666723170306785496252186e91Q,
1272       0.5443449390774430640037292402478427526443e93Q,
1273       0.3647111091818868528824985909660546442717e95Q,
1274       0.2480035542436830599600990418569171581047e97Q,
1275       0.1711224524281413113724683388812728390923e99Q,
1276       0.1197857166996989179607278372168909873646e101Q,
1277       0.8504785885678623175211676442399260102886e102Q,
1278       0.6123445837688608686152407038527467274078e104Q,
1279       0.4470115461512684340891257138125051110077e106Q,
1280       0.3307885441519386412259530282212537821457e108Q,
1281       0.2480914081139539809194647711659403366093e110Q,
1282       0.188549470166605025498793226086114655823e112Q,
1283       0.1451830920282858696340707840863082849837e114Q,
1284       0.1132428117820629783145752115873204622873e116Q,
1285       0.8946182130782975286851441715398316520698e117Q,
1286       0.7156945704626380229481153372318653216558e119Q,
1287       0.5797126020747367985879734231578109105412e121Q,
1288       0.4753643337012841748421382069894049466438e123Q,
1289       0.3945523969720658651189747118012061057144e125Q,
1290       0.3314240134565353266999387579130131288001e127Q,
1291       0.2817104114380550276949479442260611594801e129Q,
1292       0.2422709538367273238176552320344125971528e131Q,
1293       0.210775729837952771721360051869938959523e133Q,
1294       0.1854826422573984391147968456455462843802e135Q,
1295       0.1650795516090846108121691926245361930984e137Q,
1296       0.1485715964481761497309522733620825737886e139Q,
1297       0.1352001527678402962551665687594951421476e141Q,
1298       0.1243841405464130725547532432587355307758e143Q,
1299       0.1156772507081641574759205162306240436215e145Q,
1300       0.1087366156656743080273652852567866010042e147Q,
1301       0.103299784882390592625997020993947270954e149Q,
1302       0.9916779348709496892095714015418938011582e150Q,
1303       0.9619275968248211985332842594956369871234e152Q,
1304       0.942689044888324774562618574305724247381e154Q,
1305       0.9332621544394415268169923885626670049072e156Q,
1306       0.9332621544394415268169923885626670049072e158Q,
1307       0.9425947759838359420851623124482936749562e160Q,
1308       0.9614466715035126609268655586972595484554e162Q,
1309       0.990290071648618040754671525458177334909e164Q,
1310       0.1029901674514562762384858386476504428305e167Q,
1311       0.1081396758240290900504101305800329649721e169Q,
1312       0.1146280563734708354534347384148349428704e171Q,
1313       0.1226520203196137939351751701038733888713e173Q,
1314       0.132464181945182897449989183712183259981e175Q,
1315       0.1443859583202493582204882102462797533793e177Q,
1316       0.1588245541522742940425370312709077287172e179Q,
1317       0.1762952551090244663872161047107075788761e181Q,
1318       0.1974506857221074023536820372759924883413e183Q,
1319       0.2231192748659813646596607021218715118256e185Q,
1320       0.2543559733472187557120132004189335234812e187Q,
1321       0.2925093693493015690688151804817735520034e189Q,
1322       0.339310868445189820119825609358857320324e191Q,
1323       0.396993716080872089540195962949863064779e193Q,
1324       0.4684525849754290656574312362808384164393e195Q,
1325       0.5574585761207605881323431711741977155627e197Q,
1326       0.6689502913449127057588118054090372586753e199Q,
1327       0.8094298525273443739681622845449350829971e201Q,
1328       0.9875044200833601362411579871448208012564e203Q,
1329       0.1214630436702532967576624324188129585545e206Q,
1330       0.1506141741511140879795014161993280686076e208Q,
1331       0.1882677176888926099743767702491600857595e210Q,
1332       0.237217324288004688567714730513941708057e212Q,
1333       0.3012660018457659544809977077527059692324e214Q,
1334       0.3856204823625804217356770659234636406175e216Q,
1335       0.4974504222477287440390234150412680963966e218Q,
1336       0.6466855489220473672507304395536485253155e220Q,
1337       0.8471580690878820510984568758152795681634e222Q,
1338       0.1118248651196004307449963076076169029976e225Q,
1339       0.1487270706090685728908450891181304809868e227Q,
1340       0.1992942746161518876737324194182948445223e229Q,
1341       0.269047270731805048359538766214698040105e231Q,
1342       0.3659042881952548657689727220519893345429e233Q,
1343       0.5012888748274991661034926292112253883237e235Q,
1344       0.6917786472619488492228198283114910358867e237Q,
1345       0.9615723196941089004197195613529725398826e239Q,
1346       0.1346201247571752460587607385894161555836e242Q,
1347       0.1898143759076170969428526414110767793728e244Q,
1348       0.2695364137888162776588507508037290267094e246Q,
1349       0.3854370717180072770521565736493325081944e248Q,
1350       0.5550293832739304789551054660550388118e250Q,
1351       0.80479260574719919448490292577980627711e252Q,
1352       0.1174997204390910823947958271638517164581e255Q,
1353       0.1727245890454638911203498659308620231933e257Q,
1354       0.2556323917872865588581178015776757943262e259Q,
1355       0.380892263763056972698595524350736933546e261Q,
1356       0.571338395644585459047893286526105400319e263Q,
1357       0.8627209774233240431623188626544191544816e265Q,
1358       0.1311335885683452545606724671234717114812e268Q,
1359       0.2006343905095682394778288746989117185662e270Q,
1360       0.308976961384735088795856467036324046592e272Q,
1361       0.4789142901463393876335775239063022722176e274Q,
1362       0.7471062926282894447083809372938315446595e276Q,
1363       0.1172956879426414428192158071551315525115e279Q,
1364       0.1853271869493734796543609753051078529682e281Q,
1365       0.2946702272495038326504339507351214862195e283Q,
1366       0.4714723635992061322406943211761943779512e285Q,
1367       0.7590705053947218729075178570936729485014e287Q,
1368       0.1229694218739449434110178928491750176572e290Q,
1369       0.2004401576545302577599591653441552787813e292Q,
1370       0.3287218585534296227263330311644146572013e294Q,
1371       0.5423910666131588774984495014212841843822e296Q,
1372       0.9003691705778437366474261723593317460744e298Q,
1373       0.1503616514864999040201201707840084015944e301Q,
1374       0.2526075744973198387538018869171341146786e303Q,
1375       0.4269068009004705274939251888899566538069e305Q,
1376       0.7257415615307998967396728211129263114717e307Q,
1377    } };
1378 #endif
1379 
1380 template <>
1381 inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION BOOST_MATH_FLOAT128_TYPE unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(unsigned i)
1382 {
1383    return unchecked_factorial_data<BOOST_MATH_FLOAT128_TYPE>::factorials[i];
1384 }
1385 
1386 template <>
1387 struct max_factorial<BOOST_MATH_FLOAT128_TYPE>
1388 {
1389    static constexpr unsigned value = 170;
1390 };
1391 
1392 #endif
1393 
1394 template <class T>
1395 struct unchecked_factorial_initializer
1396 {
1397    struct init
1398    {
1399       init()
1400       {
1401          boost::math::unchecked_factorial<T>(3);
1402       }
1403       void force_instantiate()const {}
1404    };
1405    static const init initializer;
1406    static void force_instantiate()
1407    {
1408       initializer.force_instantiate();
1409    }
1410 };
1411 
1412 template <class T>
1413 const typename unchecked_factorial_initializer<T>::init unchecked_factorial_initializer<T>::initializer;
1414 
1415 
1416 template <class T, int N>
1417 inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, N>&)
1418 {
1419    //
1420    // If you're foolish enough to instantiate factorial
1421    // on an integer type then you end up here.  But this code is
1422    // only intended for (fixed precision) multiprecision types.
1423    // 
1424    // Note, factorial<unsigned int>(n) is not implemented
1425    // because it would overflow integral type T for too small n
1426    // to be useful. Use instead a floating-point type,
1427    // and convert to an unsigned type if essential, for example:
1428    // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
1429    // See factorial documentation for more detail.
1430    //
1431    static_assert(!boost::math::is_integral<T>::value && !boost::math::numeric_limits<T>::is_integer, "Type T must not be an integral type");
1432 
1433    // We rely on C++11 thread safe initialization here:
1434    static const boost::math::array<T, 101> factorials = {{
1435       T(boost::math::tools::convert_from_string<T>("1")),
1436       T(boost::math::tools::convert_from_string<T>("1")),
1437       T(boost::math::tools::convert_from_string<T>("2")),
1438       T(boost::math::tools::convert_from_string<T>("6")),
1439       T(boost::math::tools::convert_from_string<T>("24")),
1440       T(boost::math::tools::convert_from_string<T>("120")),
1441       T(boost::math::tools::convert_from_string<T>("720")),
1442       T(boost::math::tools::convert_from_string<T>("5040")),
1443       T(boost::math::tools::convert_from_string<T>("40320")),
1444       T(boost::math::tools::convert_from_string<T>("362880")),
1445       T(boost::math::tools::convert_from_string<T>("3628800")),
1446       T(boost::math::tools::convert_from_string<T>("39916800")),
1447       T(boost::math::tools::convert_from_string<T>("479001600")),
1448       T(boost::math::tools::convert_from_string<T>("6227020800")),
1449       T(boost::math::tools::convert_from_string<T>("87178291200")),
1450       T(boost::math::tools::convert_from_string<T>("1307674368000")),
1451       T(boost::math::tools::convert_from_string<T>("20922789888000")),
1452       T(boost::math::tools::convert_from_string<T>("355687428096000")),
1453       T(boost::math::tools::convert_from_string<T>("6402373705728000")),
1454       T(boost::math::tools::convert_from_string<T>("121645100408832000")),
1455       T(boost::math::tools::convert_from_string<T>("2432902008176640000")),
1456       T(boost::math::tools::convert_from_string<T>("51090942171709440000")),
1457       T(boost::math::tools::convert_from_string<T>("1124000727777607680000")),
1458       T(boost::math::tools::convert_from_string<T>("25852016738884976640000")),
1459       T(boost::math::tools::convert_from_string<T>("620448401733239439360000")),
1460       T(boost::math::tools::convert_from_string<T>("15511210043330985984000000")),
1461       T(boost::math::tools::convert_from_string<T>("403291461126605635584000000")),
1462       T(boost::math::tools::convert_from_string<T>("10888869450418352160768000000")),
1463       T(boost::math::tools::convert_from_string<T>("304888344611713860501504000000")),
1464       T(boost::math::tools::convert_from_string<T>("8841761993739701954543616000000")),
1465       T(boost::math::tools::convert_from_string<T>("265252859812191058636308480000000")),
1466       T(boost::math::tools::convert_from_string<T>("8222838654177922817725562880000000")),
1467       T(boost::math::tools::convert_from_string<T>("263130836933693530167218012160000000")),
1468       T(boost::math::tools::convert_from_string<T>("8683317618811886495518194401280000000")),
1469       T(boost::math::tools::convert_from_string<T>("295232799039604140847618609643520000000")),
1470       T(boost::math::tools::convert_from_string<T>("10333147966386144929666651337523200000000")),
1471       T(boost::math::tools::convert_from_string<T>("371993326789901217467999448150835200000000")),
1472       T(boost::math::tools::convert_from_string<T>("13763753091226345046315979581580902400000000")),
1473       T(boost::math::tools::convert_from_string<T>("523022617466601111760007224100074291200000000")),
1474       T(boost::math::tools::convert_from_string<T>("20397882081197443358640281739902897356800000000")),
1475       T(boost::math::tools::convert_from_string<T>("815915283247897734345611269596115894272000000000")),
1476       T(boost::math::tools::convert_from_string<T>("33452526613163807108170062053440751665152000000000")),
1477       T(boost::math::tools::convert_from_string<T>("1405006117752879898543142606244511569936384000000000")),
1478       T(boost::math::tools::convert_from_string<T>("60415263063373835637355132068513997507264512000000000")),
1479       T(boost::math::tools::convert_from_string<T>("2658271574788448768043625811014615890319638528000000000")),
1480       T(boost::math::tools::convert_from_string<T>("119622220865480194561963161495657715064383733760000000000")),
1481       T(boost::math::tools::convert_from_string<T>("5502622159812088949850305428800254892961651752960000000000")),
1482       T(boost::math::tools::convert_from_string<T>("258623241511168180642964355153611979969197632389120000000000")),
1483       T(boost::math::tools::convert_from_string<T>("12413915592536072670862289047373375038521486354677760000000000")),
1484       T(boost::math::tools::convert_from_string<T>("608281864034267560872252163321295376887552831379210240000000000")),
1485       T(boost::math::tools::convert_from_string<T>("30414093201713378043612608166064768844377641568960512000000000000")),
1486       T(boost::math::tools::convert_from_string<T>("1551118753287382280224243016469303211063259720016986112000000000000")),
1487       T(boost::math::tools::convert_from_string<T>("80658175170943878571660636856403766975289505440883277824000000000000")),
1488       T(boost::math::tools::convert_from_string<T>("4274883284060025564298013753389399649690343788366813724672000000000000")),
1489       T(boost::math::tools::convert_from_string<T>("230843697339241380472092742683027581083278564571807941132288000000000000")),
1490       T(boost::math::tools::convert_from_string<T>("12696403353658275925965100847566516959580321051449436762275840000000000000")),
1491       T(boost::math::tools::convert_from_string<T>("710998587804863451854045647463724949736497978881168458687447040000000000000")),
1492       T(boost::math::tools::convert_from_string<T>("40526919504877216755680601905432322134980384796226602145184481280000000000000")),
1493       T(boost::math::tools::convert_from_string<T>("2350561331282878571829474910515074683828862318181142924420699914240000000000000")),
1494       T(boost::math::tools::convert_from_string<T>("138683118545689835737939019720389406345902876772687432540821294940160000000000000")),
1495       T(boost::math::tools::convert_from_string<T>("8320987112741390144276341183223364380754172606361245952449277696409600000000000000")),
1496       T(boost::math::tools::convert_from_string<T>("507580213877224798800856812176625227226004528988036003099405939480985600000000000000")),
1497       T(boost::math::tools::convert_from_string<T>("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000")),
1498       T(boost::math::tools::convert_from_string<T>("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000")),
1499       T(boost::math::tools::convert_from_string<T>("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000")),
1500       T(boost::math::tools::convert_from_string<T>("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000")),
1501       T(boost::math::tools::convert_from_string<T>("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000")),
1502       T(boost::math::tools::convert_from_string<T>("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000")),
1503       T(boost::math::tools::convert_from_string<T>("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000")),
1504       T(boost::math::tools::convert_from_string<T>("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000")),
1505       T(boost::math::tools::convert_from_string<T>("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000")),
1506       T(boost::math::tools::convert_from_string<T>("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000")),
1507       T(boost::math::tools::convert_from_string<T>("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000")),
1508       T(boost::math::tools::convert_from_string<T>("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000")),
1509       T(boost::math::tools::convert_from_string<T>("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000")),
1510       T(boost::math::tools::convert_from_string<T>("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000")),
1511       T(boost::math::tools::convert_from_string<T>("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000")),
1512       T(boost::math::tools::convert_from_string<T>("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000")),
1513       T(boost::math::tools::convert_from_string<T>("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000")),
1514       T(boost::math::tools::convert_from_string<T>("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000")),
1515       T(boost::math::tools::convert_from_string<T>("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000")),
1516       T(boost::math::tools::convert_from_string<T>("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000")),
1517       T(boost::math::tools::convert_from_string<T>("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000")),
1518       T(boost::math::tools::convert_from_string<T>("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000")),
1519       T(boost::math::tools::convert_from_string<T>("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000")),
1520       T(boost::math::tools::convert_from_string<T>("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000")),
1521       T(boost::math::tools::convert_from_string<T>("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000")),
1522       T(boost::math::tools::convert_from_string<T>("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000")),
1523       T(boost::math::tools::convert_from_string<T>("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000")),
1524       T(boost::math::tools::convert_from_string<T>("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000")),
1525       T(boost::math::tools::convert_from_string<T>("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000")),
1526       T(boost::math::tools::convert_from_string<T>("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000")),
1527       T(boost::math::tools::convert_from_string<T>("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000")),
1528       T(boost::math::tools::convert_from_string<T>("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000")),
1529       T(boost::math::tools::convert_from_string<T>("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000")),
1530       T(boost::math::tools::convert_from_string<T>("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000")),
1531       T(boost::math::tools::convert_from_string<T>("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000")),
1532       T(boost::math::tools::convert_from_string<T>("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000")),
1533       T(boost::math::tools::convert_from_string<T>("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000")),
1534       T(boost::math::tools::convert_from_string<T>("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000")),
1535       T(boost::math::tools::convert_from_string<T>("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000")),
1536    }};
1537 
1538    return factorials[i];
1539 }
1540 
1541 template <class T>
1542 inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, 0>&)
1543 {
1544    //
1545    // If you're foolish enough to instantiate factorial
1546    // on an integer type then you end up here.  But this code is
1547    // only intended for (variable precision) multiprecision types.
1548    // 
1549    // Note, factorial<unsigned int>(n) is not implemented
1550    // because it would overflow integral type T for too small n
1551    // to be useful. Use instead a floating-point type,
1552    // and convert to an unsigned type if essential, for example:
1553    // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
1554    // See factorial documentation for more detail.
1555    //
1556    static_assert(!boost::math::is_integral<T>::value && !boost::math::numeric_limits<T>::is_integer, "Type T must not be an integral type");
1557 
1558    static const char* const factorial_strings[] = {
1559          "1",
1560          "1",
1561          "2",
1562          "6",
1563          "24",
1564          "120",
1565          "720",
1566          "5040",
1567          "40320",
1568          "362880",
1569          "3628800",
1570          "39916800",
1571          "479001600",
1572          "6227020800",
1573          "87178291200",
1574          "1307674368000",
1575          "20922789888000",
1576          "355687428096000",
1577          "6402373705728000",
1578          "121645100408832000",
1579          "2432902008176640000",
1580          "51090942171709440000",
1581          "1124000727777607680000",
1582          "25852016738884976640000",
1583          "620448401733239439360000",
1584          "15511210043330985984000000",
1585          "403291461126605635584000000",
1586          "10888869450418352160768000000",
1587          "304888344611713860501504000000",
1588          "8841761993739701954543616000000",
1589          "265252859812191058636308480000000",
1590          "8222838654177922817725562880000000",
1591          "263130836933693530167218012160000000",
1592          "8683317618811886495518194401280000000",
1593          "295232799039604140847618609643520000000",
1594          "10333147966386144929666651337523200000000",
1595          "371993326789901217467999448150835200000000",
1596          "13763753091226345046315979581580902400000000",
1597          "523022617466601111760007224100074291200000000",
1598          "20397882081197443358640281739902897356800000000",
1599          "815915283247897734345611269596115894272000000000",
1600          "33452526613163807108170062053440751665152000000000",
1601          "1405006117752879898543142606244511569936384000000000",
1602          "60415263063373835637355132068513997507264512000000000",
1603          "2658271574788448768043625811014615890319638528000000000",
1604          "119622220865480194561963161495657715064383733760000000000",
1605          "5502622159812088949850305428800254892961651752960000000000",
1606          "258623241511168180642964355153611979969197632389120000000000",
1607          "12413915592536072670862289047373375038521486354677760000000000",
1608          "608281864034267560872252163321295376887552831379210240000000000",
1609          "30414093201713378043612608166064768844377641568960512000000000000",
1610          "1551118753287382280224243016469303211063259720016986112000000000000",
1611          "80658175170943878571660636856403766975289505440883277824000000000000",
1612          "4274883284060025564298013753389399649690343788366813724672000000000000",
1613          "230843697339241380472092742683027581083278564571807941132288000000000000",
1614          "12696403353658275925965100847566516959580321051449436762275840000000000000",
1615          "710998587804863451854045647463724949736497978881168458687447040000000000000",
1616          "40526919504877216755680601905432322134980384796226602145184481280000000000000",
1617          "2350561331282878571829474910515074683828862318181142924420699914240000000000000",
1618          "138683118545689835737939019720389406345902876772687432540821294940160000000000000",
1619          "8320987112741390144276341183223364380754172606361245952449277696409600000000000000",
1620          "507580213877224798800856812176625227226004528988036003099405939480985600000000000000",
1621          "31469973260387937525653122354950764088012280797258232192163168247821107200000000000000",
1622          "1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000",
1623          "126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000",
1624          "8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000",
1625          "544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000",
1626          "36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000",
1627          "2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000",
1628          "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000",
1629          "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000",
1630          "850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000",
1631          "61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000",
1632          "4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000",
1633          "330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000",
1634          "24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000",
1635          "1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000",
1636          "145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000",
1637          "11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000",
1638          "894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000",
1639          "71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000",
1640          "5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000",
1641          "475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000",
1642          "39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000",
1643          "3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000",
1644          "281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000",
1645          "24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000",
1646          "2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000",
1647          "185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000",
1648          "16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000",
1649          "1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000",
1650          "135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000",
1651          "12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000",
1652          "1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000",
1653          "108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000",
1654          "10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000",
1655          "991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000",
1656          "96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000",
1657          "9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000",
1658          "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000",
1659          "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000",
1660       };
1661       //
1662       // we rely on C++11 thread safe initialization in the event that we have no thread locals:
1663       //
1664       static BOOST_MATH_THREAD_LOCAL T factorials[sizeof(factorial_strings) / sizeof(factorial_strings[0])];
1665       static BOOST_MATH_THREAD_LOCAL int digits = 0;
1666 
1667       int current_digits = boost::math::tools::digits<T>();
1668 
1669       if(digits != current_digits)
1670       {
1671          digits = current_digits;
1672          for(unsigned k = 0; k < sizeof(factorials) / sizeof(factorials[0]); ++k)
1673             factorials[k] = static_cast<T>(boost::math::tools::convert_from_string<T>(factorial_strings[k]));
1674       }
1675 
1676    return factorials[i];
1677 }
1678 
1679 #endif // BOOST_MATH_HAS_GPU_SUPPORT
1680 
1681 template <class T>
1682 BOOST_MATH_GPU_ENABLED inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, boost::math::numeric_limits<float>::digits>&)
1683 {
1684    return unchecked_factorial<float>(i);
1685 }
1686 
1687 template <class T>
1688 BOOST_MATH_GPU_ENABLED inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, boost::math::numeric_limits<double>::digits>&)
1689 {
1690    return unchecked_factorial<double>(i);
1691 }
1692 
1693 #ifndef BOOST_MATH_HAS_GPU_SUPPORT
1694 
1695 #if DBL_MANT_DIG != LDBL_MANT_DIG
1696 template <class T>
1697 inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, LDBL_MANT_DIG>&)
1698 {
1699    return unchecked_factorial<long double>(i);
1700 }
1701 #endif
1702 #ifdef BOOST_MATH_USE_FLOAT128
1703 template <class T>
1704 inline T unchecked_factorial_imp(unsigned i, const boost::math::integral_constant<int, 113>&)
1705 {
1706    return unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(i);
1707 }
1708 #endif
1709 
1710 #endif // BOOST_MATH_HAS_GPU_SUPPORT
1711 
1712 template <class T>
1713 BOOST_MATH_GPU_ENABLED inline T unchecked_factorial(unsigned i)
1714 {
1715    typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type tag_type;
1716    return unchecked_factorial_imp<T>(i, tag_type());
1717 }
1718 
1719 #ifdef BOOST_MATH_USE_FLOAT128
1720 #define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL : boost::math::numeric_limits<T>::digits == 113 ? max_factorial<BOOST_MATH_FLOAT128_TYPE>::value
1721 #else
1722 #define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
1723 #endif
1724 
1725 template <class T>
1726 struct max_factorial
1727 {
1728    static constexpr unsigned value = 
1729       boost::math::numeric_limits<T>::digits == boost::math::numeric_limits<float>::digits ? max_factorial<float>::value 
1730       : boost::math::numeric_limits<T>::digits == boost::math::numeric_limits<double>::digits ? max_factorial<double>::value
1731       #ifndef BOOST_MATH_GPU_ENABLED 
1732       : boost::math::numeric_limits<T>::digits == boost::math::numeric_limits<long double>::digits ? max_factorial<long double>::value 
1733       BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
1734       #endif
1735       : 100;
1736 };
1737 
1738 #undef BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
1739 
1740 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
1741 template <class T>
1742 constexpr unsigned max_factorial<T>::value;
1743 #endif
1744 
1745 } // namespace math
1746 } // namespace boost
1747 
1748 #endif // BOOST_MATH_SP_UC_FACTORIALS_HPP
1749