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