]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/math/special_functions/detail/unchecked_factorial.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / math / special_functions / detail / unchecked_factorial.hpp
CommitLineData
7c673cae
FG
1// Copyright John Maddock 2006.
2// Use, modification and distribution are subject to the
3// Boost Software License, Version 1.0. (See accompanying file
4// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef BOOST_MATH_SP_UC_FACTORIALS_HPP
7#define BOOST_MATH_SP_UC_FACTORIALS_HPP
8
9#ifdef _MSC_VER
10#pragma once
11#endif
12
7c673cae
FG
13#ifdef BOOST_MSVC
14#pragma warning(push) // Temporary until lexical cast fixed.
15#pragma warning(disable: 4127 4701)
16#endif
17#ifndef BOOST_MATH_NO_LEXICAL_CAST
18#include <boost/lexical_cast.hpp>
19#endif
20#ifdef BOOST_MSVC
21#pragma warning(pop)
22#endif
11fdf7f2 23#include <cmath>
7c673cae
FG
24#include <boost/math/special_functions/math_fwd.hpp>
25
11fdf7f2
TL
26#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
27#include <array>
28#else
29#include <boost/array.hpp>
30#endif
31
92f5a8d4
TL
32#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
33//
34// This is the only way we can avoid
35// warning: non-standard suffix on floating constant [-Wpedantic]
36// when building with -Wall -pedantic. Neither __extension__
37// nor #pragma dianostic ignored work :(
38//
39#pragma GCC system_header
40#endif
41
7c673cae
FG
42namespace boost { namespace math
43{
44// Forward declarations:
45template <class T>
46struct max_factorial;
47
48// Definitions:
49template <>
11fdf7f2 50inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial<float>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float))
7c673cae 51{
11fdf7f2
TL
52#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
53 constexpr std::array<float, 35> factorials = { {
54#else
7c673cae 55 static const boost::array<float, 35> factorials = {{
11fdf7f2 56#endif
7c673cae
FG
57 1.0F,
58 1.0F,
59 2.0F,
60 6.0F,
61 24.0F,
62 120.0F,
63 720.0F,
64 5040.0F,
65 40320.0F,
66 362880.0F,
67 3628800.0F,
68 39916800.0F,
69 479001600.0F,
70 6227020800.0F,
71 87178291200.0F,
72 1307674368000.0F,
73 20922789888000.0F,
74 355687428096000.0F,
75 6402373705728000.0F,
76 121645100408832000.0F,
77 0.243290200817664e19F,
78 0.5109094217170944e20F,
79 0.112400072777760768e22F,
80 0.2585201673888497664e23F,
81 0.62044840173323943936e24F,
82 0.15511210043330985984e26F,
83 0.403291461126605635584e27F,
84 0.10888869450418352160768e29F,
85 0.304888344611713860501504e30F,
86 0.8841761993739701954543616e31F,
87 0.26525285981219105863630848e33F,
88 0.822283865417792281772556288e34F,
89 0.26313083693369353016721801216e36F,
90 0.868331761881188649551819440128e37F,
91 0.29523279903960414084761860964352e39F,
92 }};
93
94 return factorials[i];
95}
96
97template <>
98struct max_factorial<float>
99{
100 BOOST_STATIC_CONSTANT(unsigned, value = 34);
101};
102
103
104template <>
11fdf7f2 105inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION long double unchecked_factorial<long double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double))
7c673cae 106{
11fdf7f2
TL
107#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
108 constexpr std::array<long double, 171> factorials = { {
109#else
7c673cae 110 static const boost::array<long double, 171> factorials = {{
11fdf7f2 111#endif
7c673cae
FG
112 1L,
113 1L,
114 2L,
115 6L,
116 24L,
117 120L,
118 720L,
119 5040L,
120 40320L,
121 362880.0L,
122 3628800.0L,
123 39916800.0L,
124 479001600.0L,
125 6227020800.0L,
126 87178291200.0L,
127 1307674368000.0L,
128 20922789888000.0L,
129 355687428096000.0L,
130 6402373705728000.0L,
131 121645100408832000.0L,
132 0.243290200817664e19L,
133 0.5109094217170944e20L,
134 0.112400072777760768e22L,
135 0.2585201673888497664e23L,
136 0.62044840173323943936e24L,
137 0.15511210043330985984e26L,
138 0.403291461126605635584e27L,
139 0.10888869450418352160768e29L,
140 0.304888344611713860501504e30L,
141 0.8841761993739701954543616e31L,
142 0.26525285981219105863630848e33L,
143 0.822283865417792281772556288e34L,
144 0.26313083693369353016721801216e36L,
145 0.868331761881188649551819440128e37L,
146 0.29523279903960414084761860964352e39L,
147 0.103331479663861449296666513375232e41L,
148 0.3719933267899012174679994481508352e42L,
149 0.137637530912263450463159795815809024e44L,
150 0.5230226174666011117600072241000742912e45L,
151 0.203978820811974433586402817399028973568e47L,
152 0.815915283247897734345611269596115894272e48L,
153 0.3345252661316380710817006205344075166515e50L,
154 0.1405006117752879898543142606244511569936e52L,
155 0.6041526306337383563735513206851399750726e53L,
156 0.265827157478844876804362581101461589032e55L,
157 0.1196222208654801945619631614956577150644e57L,
158 0.5502622159812088949850305428800254892962e58L,
159 0.2586232415111681806429643551536119799692e60L,
160 0.1241391559253607267086228904737337503852e62L,
161 0.6082818640342675608722521633212953768876e63L,
162 0.3041409320171337804361260816606476884438e65L,
163 0.1551118753287382280224243016469303211063e67L,
164 0.8065817517094387857166063685640376697529e68L,
165 0.427488328406002556429801375338939964969e70L,
166 0.2308436973392413804720927426830275810833e72L,
167 0.1269640335365827592596510084756651695958e74L,
168 0.7109985878048634518540456474637249497365e75L,
169 0.4052691950487721675568060190543232213498e77L,
170 0.2350561331282878571829474910515074683829e79L,
171 0.1386831185456898357379390197203894063459e81L,
172 0.8320987112741390144276341183223364380754e82L,
173 0.507580213877224798800856812176625227226e84L,
174 0.3146997326038793752565312235495076408801e86L,
175 0.1982608315404440064116146708361898137545e88L,
176 0.1268869321858841641034333893351614808029e90L,
177 0.8247650592082470666723170306785496252186e91L,
178 0.5443449390774430640037292402478427526443e93L,
179 0.3647111091818868528824985909660546442717e95L,
180 0.2480035542436830599600990418569171581047e97L,
181 0.1711224524281413113724683388812728390923e99L,
182 0.1197857166996989179607278372168909873646e101L,
183 0.8504785885678623175211676442399260102886e102L,
184 0.6123445837688608686152407038527467274078e104L,
185 0.4470115461512684340891257138125051110077e106L,
186 0.3307885441519386412259530282212537821457e108L,
187 0.2480914081139539809194647711659403366093e110L,
188 0.188549470166605025498793226086114655823e112L,
189 0.1451830920282858696340707840863082849837e114L,
190 0.1132428117820629783145752115873204622873e116L,
191 0.8946182130782975286851441715398316520698e117L,
192 0.7156945704626380229481153372318653216558e119L,
193 0.5797126020747367985879734231578109105412e121L,
194 0.4753643337012841748421382069894049466438e123L,
195 0.3945523969720658651189747118012061057144e125L,
196 0.3314240134565353266999387579130131288001e127L,
197 0.2817104114380550276949479442260611594801e129L,
198 0.2422709538367273238176552320344125971528e131L,
199 0.210775729837952771721360051869938959523e133L,
200 0.1854826422573984391147968456455462843802e135L,
201 0.1650795516090846108121691926245361930984e137L,
202 0.1485715964481761497309522733620825737886e139L,
203 0.1352001527678402962551665687594951421476e141L,
204 0.1243841405464130725547532432587355307758e143L,
205 0.1156772507081641574759205162306240436215e145L,
206 0.1087366156656743080273652852567866010042e147L,
207 0.103299784882390592625997020993947270954e149L,
208 0.9916779348709496892095714015418938011582e150L,
209 0.9619275968248211985332842594956369871234e152L,
210 0.942689044888324774562618574305724247381e154L,
211 0.9332621544394415268169923885626670049072e156L,
212 0.9332621544394415268169923885626670049072e158L,
213 0.9425947759838359420851623124482936749562e160L,
214 0.9614466715035126609268655586972595484554e162L,
215 0.990290071648618040754671525458177334909e164L,
216 0.1029901674514562762384858386476504428305e167L,
217 0.1081396758240290900504101305800329649721e169L,
218 0.1146280563734708354534347384148349428704e171L,
219 0.1226520203196137939351751701038733888713e173L,
220 0.132464181945182897449989183712183259981e175L,
221 0.1443859583202493582204882102462797533793e177L,
222 0.1588245541522742940425370312709077287172e179L,
223 0.1762952551090244663872161047107075788761e181L,
224 0.1974506857221074023536820372759924883413e183L,
225 0.2231192748659813646596607021218715118256e185L,
226 0.2543559733472187557120132004189335234812e187L,
227 0.2925093693493015690688151804817735520034e189L,
228 0.339310868445189820119825609358857320324e191L,
229 0.396993716080872089540195962949863064779e193L,
230 0.4684525849754290656574312362808384164393e195L,
231 0.5574585761207605881323431711741977155627e197L,
232 0.6689502913449127057588118054090372586753e199L,
233 0.8094298525273443739681622845449350829971e201L,
234 0.9875044200833601362411579871448208012564e203L,
235 0.1214630436702532967576624324188129585545e206L,
236 0.1506141741511140879795014161993280686076e208L,
237 0.1882677176888926099743767702491600857595e210L,
238 0.237217324288004688567714730513941708057e212L,
239 0.3012660018457659544809977077527059692324e214L,
240 0.3856204823625804217356770659234636406175e216L,
241 0.4974504222477287440390234150412680963966e218L,
242 0.6466855489220473672507304395536485253155e220L,
243 0.8471580690878820510984568758152795681634e222L,
244 0.1118248651196004307449963076076169029976e225L,
245 0.1487270706090685728908450891181304809868e227L,
246 0.1992942746161518876737324194182948445223e229L,
247 0.269047270731805048359538766214698040105e231L,
248 0.3659042881952548657689727220519893345429e233L,
249 0.5012888748274991661034926292112253883237e235L,
250 0.6917786472619488492228198283114910358867e237L,
251 0.9615723196941089004197195613529725398826e239L,
252 0.1346201247571752460587607385894161555836e242L,
253 0.1898143759076170969428526414110767793728e244L,
254 0.2695364137888162776588507508037290267094e246L,
255 0.3854370717180072770521565736493325081944e248L,
256 0.5550293832739304789551054660550388118e250L,
257 0.80479260574719919448490292577980627711e252L,
258 0.1174997204390910823947958271638517164581e255L,
259 0.1727245890454638911203498659308620231933e257L,
260 0.2556323917872865588581178015776757943262e259L,
261 0.380892263763056972698595524350736933546e261L,
262 0.571338395644585459047893286526105400319e263L,
263 0.8627209774233240431623188626544191544816e265L,
264 0.1311335885683452545606724671234717114812e268L,
265 0.2006343905095682394778288746989117185662e270L,
266 0.308976961384735088795856467036324046592e272L,
267 0.4789142901463393876335775239063022722176e274L,
268 0.7471062926282894447083809372938315446595e276L,
269 0.1172956879426414428192158071551315525115e279L,
270 0.1853271869493734796543609753051078529682e281L,
271 0.2946702272495038326504339507351214862195e283L,
272 0.4714723635992061322406943211761943779512e285L,
273 0.7590705053947218729075178570936729485014e287L,
274 0.1229694218739449434110178928491750176572e290L,
275 0.2004401576545302577599591653441552787813e292L,
276 0.3287218585534296227263330311644146572013e294L,
277 0.5423910666131588774984495014212841843822e296L,
278 0.9003691705778437366474261723593317460744e298L,
279 0.1503616514864999040201201707840084015944e301L,
280 0.2526075744973198387538018869171341146786e303L,
281 0.4269068009004705274939251888899566538069e305L,
282 0.7257415615307998967396728211129263114717e307L,
283 }};
284
285 return factorials[i];
286}
287
288template <>
289struct max_factorial<long double>
290{
291 BOOST_STATIC_CONSTANT(unsigned, value = 170);
292};
293
294#ifdef BOOST_MATH_USE_FLOAT128
295
296template <>
11fdf7f2 297inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION BOOST_MATH_FLOAT128_TYPE unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(unsigned i)
7c673cae 298{
11fdf7f2
TL
299#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES
300 constexpr std::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
301#else
7c673cae 302 static const boost::array<BOOST_MATH_FLOAT128_TYPE, 171> factorials = { {
11fdf7f2 303#endif
7c673cae
FG
304 1,
305 1,
306 2,
307 6,
308 24,
309 120,
310 720,
311 5040,
312 40320,
313 362880.0Q,
314 3628800.0Q,
315 39916800.0Q,
316 479001600.0Q,
317 6227020800.0Q,
318 87178291200.0Q,
319 1307674368000.0Q,
320 20922789888000.0Q,
321 355687428096000.0Q,
322 6402373705728000.0Q,
323 121645100408832000.0Q,
324 0.243290200817664e19Q,
325 0.5109094217170944e20Q,
326 0.112400072777760768e22Q,
327 0.2585201673888497664e23Q,
328 0.62044840173323943936e24Q,
329 0.15511210043330985984e26Q,
330 0.403291461126605635584e27Q,
331 0.10888869450418352160768e29Q,
332 0.304888344611713860501504e30Q,
333 0.8841761993739701954543616e31Q,
334 0.26525285981219105863630848e33Q,
335 0.822283865417792281772556288e34Q,
336 0.26313083693369353016721801216e36Q,
337 0.868331761881188649551819440128e37Q,
338 0.29523279903960414084761860964352e39Q,
339 0.103331479663861449296666513375232e41Q,
340 0.3719933267899012174679994481508352e42Q,
341 0.137637530912263450463159795815809024e44Q,
342 0.5230226174666011117600072241000742912e45Q,
343 0.203978820811974433586402817399028973568e47Q,
344 0.815915283247897734345611269596115894272e48Q,
345 0.3345252661316380710817006205344075166515e50Q,
346 0.1405006117752879898543142606244511569936e52Q,
347 0.6041526306337383563735513206851399750726e53Q,
348 0.265827157478844876804362581101461589032e55Q,
349 0.1196222208654801945619631614956577150644e57Q,
350 0.5502622159812088949850305428800254892962e58Q,
351 0.2586232415111681806429643551536119799692e60Q,
352 0.1241391559253607267086228904737337503852e62Q,
353 0.6082818640342675608722521633212953768876e63Q,
354 0.3041409320171337804361260816606476884438e65Q,
355 0.1551118753287382280224243016469303211063e67Q,
356 0.8065817517094387857166063685640376697529e68Q,
357 0.427488328406002556429801375338939964969e70Q,
358 0.2308436973392413804720927426830275810833e72Q,
359 0.1269640335365827592596510084756651695958e74Q,
360 0.7109985878048634518540456474637249497365e75Q,
361 0.4052691950487721675568060190543232213498e77Q,
362 0.2350561331282878571829474910515074683829e79Q,
363 0.1386831185456898357379390197203894063459e81Q,
364 0.8320987112741390144276341183223364380754e82Q,
365 0.507580213877224798800856812176625227226e84Q,
366 0.3146997326038793752565312235495076408801e86Q,
367 0.1982608315404440064116146708361898137545e88Q,
368 0.1268869321858841641034333893351614808029e90Q,
369 0.8247650592082470666723170306785496252186e91Q,
370 0.5443449390774430640037292402478427526443e93Q,
371 0.3647111091818868528824985909660546442717e95Q,
372 0.2480035542436830599600990418569171581047e97Q,
373 0.1711224524281413113724683388812728390923e99Q,
374 0.1197857166996989179607278372168909873646e101Q,
375 0.8504785885678623175211676442399260102886e102Q,
376 0.6123445837688608686152407038527467274078e104Q,
377 0.4470115461512684340891257138125051110077e106Q,
378 0.3307885441519386412259530282212537821457e108Q,
379 0.2480914081139539809194647711659403366093e110Q,
380 0.188549470166605025498793226086114655823e112Q,
381 0.1451830920282858696340707840863082849837e114Q,
382 0.1132428117820629783145752115873204622873e116Q,
383 0.8946182130782975286851441715398316520698e117Q,
384 0.7156945704626380229481153372318653216558e119Q,
385 0.5797126020747367985879734231578109105412e121Q,
386 0.4753643337012841748421382069894049466438e123Q,
387 0.3945523969720658651189747118012061057144e125Q,
388 0.3314240134565353266999387579130131288001e127Q,
389 0.2817104114380550276949479442260611594801e129Q,
390 0.2422709538367273238176552320344125971528e131Q,
391 0.210775729837952771721360051869938959523e133Q,
392 0.1854826422573984391147968456455462843802e135Q,
393 0.1650795516090846108121691926245361930984e137Q,
394 0.1485715964481761497309522733620825737886e139Q,
395 0.1352001527678402962551665687594951421476e141Q,
396 0.1243841405464130725547532432587355307758e143Q,
397 0.1156772507081641574759205162306240436215e145Q,
398 0.1087366156656743080273652852567866010042e147Q,
399 0.103299784882390592625997020993947270954e149Q,
400 0.9916779348709496892095714015418938011582e150Q,
401 0.9619275968248211985332842594956369871234e152Q,
402 0.942689044888324774562618574305724247381e154Q,
403 0.9332621544394415268169923885626670049072e156Q,
404 0.9332621544394415268169923885626670049072e158Q,
405 0.9425947759838359420851623124482936749562e160Q,
406 0.9614466715035126609268655586972595484554e162Q,
407 0.990290071648618040754671525458177334909e164Q,
408 0.1029901674514562762384858386476504428305e167Q,
409 0.1081396758240290900504101305800329649721e169Q,
410 0.1146280563734708354534347384148349428704e171Q,
411 0.1226520203196137939351751701038733888713e173Q,
412 0.132464181945182897449989183712183259981e175Q,
413 0.1443859583202493582204882102462797533793e177Q,
414 0.1588245541522742940425370312709077287172e179Q,
415 0.1762952551090244663872161047107075788761e181Q,
416 0.1974506857221074023536820372759924883413e183Q,
417 0.2231192748659813646596607021218715118256e185Q,
418 0.2543559733472187557120132004189335234812e187Q,
419 0.2925093693493015690688151804817735520034e189Q,
420 0.339310868445189820119825609358857320324e191Q,
421 0.396993716080872089540195962949863064779e193Q,
422 0.4684525849754290656574312362808384164393e195Q,
423 0.5574585761207605881323431711741977155627e197Q,
424 0.6689502913449127057588118054090372586753e199Q,
425 0.8094298525273443739681622845449350829971e201Q,
426 0.9875044200833601362411579871448208012564e203Q,
427 0.1214630436702532967576624324188129585545e206Q,
428 0.1506141741511140879795014161993280686076e208Q,
429 0.1882677176888926099743767702491600857595e210Q,
430 0.237217324288004688567714730513941708057e212Q,
431 0.3012660018457659544809977077527059692324e214Q,
432 0.3856204823625804217356770659234636406175e216Q,
433 0.4974504222477287440390234150412680963966e218Q,
434 0.6466855489220473672507304395536485253155e220Q,
435 0.8471580690878820510984568758152795681634e222Q,
436 0.1118248651196004307449963076076169029976e225Q,
437 0.1487270706090685728908450891181304809868e227Q,
438 0.1992942746161518876737324194182948445223e229Q,
439 0.269047270731805048359538766214698040105e231Q,
440 0.3659042881952548657689727220519893345429e233Q,
441 0.5012888748274991661034926292112253883237e235Q,
442 0.6917786472619488492228198283114910358867e237Q,
443 0.9615723196941089004197195613529725398826e239Q,
444 0.1346201247571752460587607385894161555836e242Q,
445 0.1898143759076170969428526414110767793728e244Q,
446 0.2695364137888162776588507508037290267094e246Q,
447 0.3854370717180072770521565736493325081944e248Q,
448 0.5550293832739304789551054660550388118e250Q,
449 0.80479260574719919448490292577980627711e252Q,
450 0.1174997204390910823947958271638517164581e255Q,
451 0.1727245890454638911203498659308620231933e257Q,
452 0.2556323917872865588581178015776757943262e259Q,
453 0.380892263763056972698595524350736933546e261Q,
454 0.571338395644585459047893286526105400319e263Q,
455 0.8627209774233240431623188626544191544816e265Q,
456 0.1311335885683452545606724671234717114812e268Q,
457 0.2006343905095682394778288746989117185662e270Q,
458 0.308976961384735088795856467036324046592e272Q,
459 0.4789142901463393876335775239063022722176e274Q,
460 0.7471062926282894447083809372938315446595e276Q,
461 0.1172956879426414428192158071551315525115e279Q,
462 0.1853271869493734796543609753051078529682e281Q,
463 0.2946702272495038326504339507351214862195e283Q,
464 0.4714723635992061322406943211761943779512e285Q,
465 0.7590705053947218729075178570936729485014e287Q,
466 0.1229694218739449434110178928491750176572e290Q,
467 0.2004401576545302577599591653441552787813e292Q,
468 0.3287218585534296227263330311644146572013e294Q,
469 0.5423910666131588774984495014212841843822e296Q,
470 0.9003691705778437366474261723593317460744e298Q,
471 0.1503616514864999040201201707840084015944e301Q,
472 0.2526075744973198387538018869171341146786e303Q,
473 0.4269068009004705274939251888899566538069e305Q,
474 0.7257415615307998967396728211129263114717e307Q,
475 } };
476
477 return factorials[i];
478}
479
480template <>
481struct max_factorial<BOOST_MATH_FLOAT128_TYPE>
482{
483 BOOST_STATIC_CONSTANT(unsigned, value = 170);
484};
485
486#endif
487
488template <>
11fdf7f2 489inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial<double>(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double))
7c673cae
FG
490{
491 return static_cast<double>(boost::math::unchecked_factorial<long double>(i));
492}
493
494template <>
495struct max_factorial<double>
496{
497 BOOST_STATIC_CONSTANT(unsigned,
498 value = ::boost::math::max_factorial<long double>::value);
499};
500
501#ifndef BOOST_MATH_NO_LEXICAL_CAST
502
503template <class T>
504struct unchecked_factorial_initializer
505{
506 struct init
507 {
508 init()
509 {
510 boost::math::unchecked_factorial<T>(3);
511 }
512 void force_instantiate()const {}
513 };
514 static const init initializer;
515 static void force_instantiate()
516 {
517 initializer.force_instantiate();
518 }
519};
520
521template <class T>
522const typename unchecked_factorial_initializer<T>::init unchecked_factorial_initializer<T>::initializer;
523
524
525template <class T, int N>
526inline T unchecked_factorial_imp(unsigned i, const mpl::int_<N>&)
527{
528 BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
529 // factorial<unsigned int>(n) is not implemented
530 // because it would overflow integral type T for too small n
531 // to be useful. Use instead a floating-point type,
532 // and convert to an unsigned type if essential, for example:
533 // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
534 // See factorial documentation for more detail.
535
536 unchecked_factorial_initializer<T>::force_instantiate();
537
538 static const boost::array<T, 101> factorials = {{
539 T(boost::math::tools::convert_from_string<T>("1")),
540 T(boost::math::tools::convert_from_string<T>("1")),
541 T(boost::math::tools::convert_from_string<T>("2")),
542 T(boost::math::tools::convert_from_string<T>("6")),
543 T(boost::math::tools::convert_from_string<T>("24")),
544 T(boost::math::tools::convert_from_string<T>("120")),
545 T(boost::math::tools::convert_from_string<T>("720")),
546 T(boost::math::tools::convert_from_string<T>("5040")),
547 T(boost::math::tools::convert_from_string<T>("40320")),
548 T(boost::math::tools::convert_from_string<T>("362880")),
549 T(boost::math::tools::convert_from_string<T>("3628800")),
550 T(boost::math::tools::convert_from_string<T>("39916800")),
551 T(boost::math::tools::convert_from_string<T>("479001600")),
552 T(boost::math::tools::convert_from_string<T>("6227020800")),
553 T(boost::math::tools::convert_from_string<T>("87178291200")),
554 T(boost::math::tools::convert_from_string<T>("1307674368000")),
555 T(boost::math::tools::convert_from_string<T>("20922789888000")),
556 T(boost::math::tools::convert_from_string<T>("355687428096000")),
557 T(boost::math::tools::convert_from_string<T>("6402373705728000")),
558 T(boost::math::tools::convert_from_string<T>("121645100408832000")),
559 T(boost::math::tools::convert_from_string<T>("2432902008176640000")),
560 T(boost::math::tools::convert_from_string<T>("51090942171709440000")),
561 T(boost::math::tools::convert_from_string<T>("1124000727777607680000")),
562 T(boost::math::tools::convert_from_string<T>("25852016738884976640000")),
563 T(boost::math::tools::convert_from_string<T>("620448401733239439360000")),
564 T(boost::math::tools::convert_from_string<T>("15511210043330985984000000")),
565 T(boost::math::tools::convert_from_string<T>("403291461126605635584000000")),
566 T(boost::math::tools::convert_from_string<T>("10888869450418352160768000000")),
567 T(boost::math::tools::convert_from_string<T>("304888344611713860501504000000")),
568 T(boost::math::tools::convert_from_string<T>("8841761993739701954543616000000")),
569 T(boost::math::tools::convert_from_string<T>("265252859812191058636308480000000")),
570 T(boost::math::tools::convert_from_string<T>("8222838654177922817725562880000000")),
571 T(boost::math::tools::convert_from_string<T>("263130836933693530167218012160000000")),
572 T(boost::math::tools::convert_from_string<T>("8683317618811886495518194401280000000")),
573 T(boost::math::tools::convert_from_string<T>("295232799039604140847618609643520000000")),
574 T(boost::math::tools::convert_from_string<T>("10333147966386144929666651337523200000000")),
575 T(boost::math::tools::convert_from_string<T>("371993326789901217467999448150835200000000")),
576 T(boost::math::tools::convert_from_string<T>("13763753091226345046315979581580902400000000")),
577 T(boost::math::tools::convert_from_string<T>("523022617466601111760007224100074291200000000")),
578 T(boost::math::tools::convert_from_string<T>("20397882081197443358640281739902897356800000000")),
579 T(boost::math::tools::convert_from_string<T>("815915283247897734345611269596115894272000000000")),
580 T(boost::math::tools::convert_from_string<T>("33452526613163807108170062053440751665152000000000")),
581 T(boost::math::tools::convert_from_string<T>("1405006117752879898543142606244511569936384000000000")),
582 T(boost::math::tools::convert_from_string<T>("60415263063373835637355132068513997507264512000000000")),
583 T(boost::math::tools::convert_from_string<T>("2658271574788448768043625811014615890319638528000000000")),
584 T(boost::math::tools::convert_from_string<T>("119622220865480194561963161495657715064383733760000000000")),
585 T(boost::math::tools::convert_from_string<T>("5502622159812088949850305428800254892961651752960000000000")),
586 T(boost::math::tools::convert_from_string<T>("258623241511168180642964355153611979969197632389120000000000")),
587 T(boost::math::tools::convert_from_string<T>("12413915592536072670862289047373375038521486354677760000000000")),
588 T(boost::math::tools::convert_from_string<T>("608281864034267560872252163321295376887552831379210240000000000")),
589 T(boost::math::tools::convert_from_string<T>("30414093201713378043612608166064768844377641568960512000000000000")),
590 T(boost::math::tools::convert_from_string<T>("1551118753287382280224243016469303211063259720016986112000000000000")),
591 T(boost::math::tools::convert_from_string<T>("80658175170943878571660636856403766975289505440883277824000000000000")),
592 T(boost::math::tools::convert_from_string<T>("4274883284060025564298013753389399649690343788366813724672000000000000")),
593 T(boost::math::tools::convert_from_string<T>("230843697339241380472092742683027581083278564571807941132288000000000000")),
594 T(boost::math::tools::convert_from_string<T>("12696403353658275925965100847566516959580321051449436762275840000000000000")),
595 T(boost::math::tools::convert_from_string<T>("710998587804863451854045647463724949736497978881168458687447040000000000000")),
596 T(boost::math::tools::convert_from_string<T>("40526919504877216755680601905432322134980384796226602145184481280000000000000")),
597 T(boost::math::tools::convert_from_string<T>("2350561331282878571829474910515074683828862318181142924420699914240000000000000")),
598 T(boost::math::tools::convert_from_string<T>("138683118545689835737939019720389406345902876772687432540821294940160000000000000")),
599 T(boost::math::tools::convert_from_string<T>("8320987112741390144276341183223364380754172606361245952449277696409600000000000000")),
600 T(boost::math::tools::convert_from_string<T>("507580213877224798800856812176625227226004528988036003099405939480985600000000000000")),
601 T(boost::math::tools::convert_from_string<T>("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000")),
602 T(boost::math::tools::convert_from_string<T>("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000")),
603 T(boost::math::tools::convert_from_string<T>("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000")),
604 T(boost::math::tools::convert_from_string<T>("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000")),
605 T(boost::math::tools::convert_from_string<T>("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000")),
606 T(boost::math::tools::convert_from_string<T>("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000")),
607 T(boost::math::tools::convert_from_string<T>("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000")),
608 T(boost::math::tools::convert_from_string<T>("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000")),
609 T(boost::math::tools::convert_from_string<T>("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000")),
610 T(boost::math::tools::convert_from_string<T>("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000")),
611 T(boost::math::tools::convert_from_string<T>("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000")),
612 T(boost::math::tools::convert_from_string<T>("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000")),
613 T(boost::math::tools::convert_from_string<T>("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000")),
614 T(boost::math::tools::convert_from_string<T>("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000")),
615 T(boost::math::tools::convert_from_string<T>("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000")),
616 T(boost::math::tools::convert_from_string<T>("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000")),
617 T(boost::math::tools::convert_from_string<T>("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000")),
618 T(boost::math::tools::convert_from_string<T>("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000")),
619 T(boost::math::tools::convert_from_string<T>("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000")),
620 T(boost::math::tools::convert_from_string<T>("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000")),
621 T(boost::math::tools::convert_from_string<T>("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000")),
622 T(boost::math::tools::convert_from_string<T>("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000")),
623 T(boost::math::tools::convert_from_string<T>("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000")),
624 T(boost::math::tools::convert_from_string<T>("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000")),
625 T(boost::math::tools::convert_from_string<T>("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000")),
626 T(boost::math::tools::convert_from_string<T>("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000")),
627 T(boost::math::tools::convert_from_string<T>("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000")),
628 T(boost::math::tools::convert_from_string<T>("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000")),
629 T(boost::math::tools::convert_from_string<T>("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000")),
630 T(boost::math::tools::convert_from_string<T>("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000")),
631 T(boost::math::tools::convert_from_string<T>("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000")),
632 T(boost::math::tools::convert_from_string<T>("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000")),
633 T(boost::math::tools::convert_from_string<T>("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000")),
634 T(boost::math::tools::convert_from_string<T>("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000")),
635 T(boost::math::tools::convert_from_string<T>("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000")),
636 T(boost::math::tools::convert_from_string<T>("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000")),
637 T(boost::math::tools::convert_from_string<T>("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000")),
638 T(boost::math::tools::convert_from_string<T>("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000")),
639 T(boost::math::tools::convert_from_string<T>("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000")),
640 }};
641
642 return factorials[i];
643}
644
645template <class T>
646inline T unchecked_factorial_imp(unsigned i, const mpl::int_<0>&)
647{
648 BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
649 // factorial<unsigned int>(n) is not implemented
650 // because it would overflow integral type T for too small n
651 // to be useful. Use instead a floating-point type,
652 // and convert to an unsigned type if essential, for example:
653 // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
654 // See factorial documentation for more detail.
655#ifdef BOOST_NO_CXX11_THREAD_LOCAL
656 unchecked_factorial_initializer<T>::force_instantiate();
657#endif
658 static const char* const factorial_strings[] = {
659 "1",
660 "1",
661 "2",
662 "6",
663 "24",
664 "120",
665 "720",
666 "5040",
667 "40320",
668 "362880",
669 "3628800",
670 "39916800",
671 "479001600",
672 "6227020800",
673 "87178291200",
674 "1307674368000",
675 "20922789888000",
676 "355687428096000",
677 "6402373705728000",
678 "121645100408832000",
679 "2432902008176640000",
680 "51090942171709440000",
681 "1124000727777607680000",
682 "25852016738884976640000",
683 "620448401733239439360000",
684 "15511210043330985984000000",
685 "403291461126605635584000000",
686 "10888869450418352160768000000",
687 "304888344611713860501504000000",
688 "8841761993739701954543616000000",
689 "265252859812191058636308480000000",
690 "8222838654177922817725562880000000",
691 "263130836933693530167218012160000000",
692 "8683317618811886495518194401280000000",
693 "295232799039604140847618609643520000000",
694 "10333147966386144929666651337523200000000",
695 "371993326789901217467999448150835200000000",
696 "13763753091226345046315979581580902400000000",
697 "523022617466601111760007224100074291200000000",
698 "20397882081197443358640281739902897356800000000",
699 "815915283247897734345611269596115894272000000000",
700 "33452526613163807108170062053440751665152000000000",
701 "1405006117752879898543142606244511569936384000000000",
702 "60415263063373835637355132068513997507264512000000000",
703 "2658271574788448768043625811014615890319638528000000000",
704 "119622220865480194561963161495657715064383733760000000000",
705 "5502622159812088949850305428800254892961651752960000000000",
706 "258623241511168180642964355153611979969197632389120000000000",
707 "12413915592536072670862289047373375038521486354677760000000000",
708 "608281864034267560872252163321295376887552831379210240000000000",
709 "30414093201713378043612608166064768844377641568960512000000000000",
710 "1551118753287382280224243016469303211063259720016986112000000000000",
711 "80658175170943878571660636856403766975289505440883277824000000000000",
712 "4274883284060025564298013753389399649690343788366813724672000000000000",
713 "230843697339241380472092742683027581083278564571807941132288000000000000",
714 "12696403353658275925965100847566516959580321051449436762275840000000000000",
715 "710998587804863451854045647463724949736497978881168458687447040000000000000",
716 "40526919504877216755680601905432322134980384796226602145184481280000000000000",
717 "2350561331282878571829474910515074683828862318181142924420699914240000000000000",
718 "138683118545689835737939019720389406345902876772687432540821294940160000000000000",
719 "8320987112741390144276341183223364380754172606361245952449277696409600000000000000",
720 "507580213877224798800856812176625227226004528988036003099405939480985600000000000000",
721 "31469973260387937525653122354950764088012280797258232192163168247821107200000000000000",
722 "1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000",
723 "126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000",
724 "8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000",
725 "544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000",
726 "36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000",
727 "2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000",
728 "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000",
729 "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000",
730 "850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000",
731 "61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000",
732 "4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000",
733 "330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000",
734 "24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000",
735 "1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000",
736 "145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000",
737 "11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000",
738 "894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000",
739 "71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000",
740 "5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000",
741 "475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000",
742 "39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000",
743 "3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000",
744 "281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000",
745 "24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000",
746 "2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000",
747 "185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000",
748 "16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000",
749 "1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000",
750 "135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000",
751 "12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000",
752 "1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000",
753 "108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000",
754 "10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000",
755 "991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000",
756 "96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000",
757 "9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000",
758 "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000",
759 "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000",
760 };
761
762 static BOOST_MATH_THREAD_LOCAL T factorials[sizeof(factorial_strings) / sizeof(factorial_strings[0])];
763 static BOOST_MATH_THREAD_LOCAL int digits = 0;
764
765 int current_digits = boost::math::tools::digits<T>();
766
767 if(digits != current_digits)
768 {
769 digits = current_digits;
770 for(unsigned k = 0; k < sizeof(factorials) / sizeof(factorials[0]); ++k)
771 factorials[k] = static_cast<T>(boost::math::tools::convert_from_string<T>(factorial_strings[k]));
772 }
773
774 return factorials[i];
775}
776
92f5a8d4
TL
777template <class T>
778inline T unchecked_factorial_imp(unsigned i, const mpl::int_<std::numeric_limits<float>::digits>&)
779{
780 return unchecked_factorial<float>(i);
781}
782
783template <class T>
784inline T unchecked_factorial_imp(unsigned i, const mpl::int_<std::numeric_limits<double>::digits>&)
785{
786 return unchecked_factorial<double>(i);
787}
788
789#if DBL_MANT_DIG != LDBL_MANT_DIG
790template <class T>
791inline T unchecked_factorial_imp(unsigned i, const mpl::int_<LDBL_MANT_DIG>&)
792{
793 return unchecked_factorial<long double>(i);
794}
795#endif
796#ifdef BOOST_MATH_USE_FLOAT128
797template <class T>
798inline T unchecked_factorial_imp(unsigned i, const mpl::int_<113>&)
799{
800 return unchecked_factorial<BOOST_MATH_FLOAT128_TYPE>(i);
801}
802#endif
803
7c673cae
FG
804template <class T>
805inline T unchecked_factorial(unsigned i)
806{
807 typedef typename boost::math::policies::precision<T, boost::math::policies::policy<> >::type tag_type;
808 return unchecked_factorial_imp<T>(i, tag_type());
809}
810
92f5a8d4
TL
811#ifdef BOOST_MATH_USE_FLOAT128
812#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL : std::numeric_limits<T>::digits == 113 ? max_factorial<BOOST_MATH_FLOAT128_TYPE>::value
813#else
814#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
815#endif
816
7c673cae
FG
817template <class T>
818struct max_factorial
819{
92f5a8d4
TL
820 BOOST_STATIC_CONSTANT(unsigned, value =
821 std::numeric_limits<T>::digits == std::numeric_limits<float>::digits ? max_factorial<float>::value
822 : std::numeric_limits<T>::digits == std::numeric_limits<double>::digits ? max_factorial<double>::value
823 : std::numeric_limits<T>::digits == std::numeric_limits<long double>::digits ? max_factorial<long double>::value
824 BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
825 : 100);
7c673cae
FG
826};
827
92f5a8d4
TL
828#undef BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL
829
7c673cae
FG
830#else // BOOST_MATH_NO_LEXICAL_CAST
831
832template <class T>
833inline T unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
834{
835 return 1;
836}
837
838template <class T>
839struct max_factorial
840{
841 BOOST_STATIC_CONSTANT(unsigned, value = 0);
842};
843
844#endif
845
846#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
847template <class T>
848const unsigned max_factorial<T>::value;
849#endif
850
851} // namespace math
852} // namespace boost
853
854#endif // BOOST_MATH_SP_UC_FACTORIALS_HPP
855