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
43namespace boost { namespace math
44{
45// Forward declarations:
46template <class T>
47struct max_factorial;
48
49// Definitions:
50template <>
51inline 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 = { ._M_elems: {
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
98template <>
99struct max_factorial<float>
100{
101 BOOST_STATIC_CONSTANT(unsigned, value = 34);
102};
103
104
105template <>
106inline 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 = { ._M_elems: {
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
289template <>
290struct max_factorial<long double>
291{
292 BOOST_STATIC_CONSTANT(unsigned, value = 170);
293};
294
295#ifdef BOOST_MATH_USE_FLOAT128
296
297template <>
298inline 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
481template <>
482struct max_factorial<BOOST_MATH_FLOAT128_TYPE>
483{
484 BOOST_STATIC_CONSTANT(unsigned, value = 170);
485};
486
487#endif
488
489template <>
490inline 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
495template <>
496struct 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
504template <class T>
505struct 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
522template <class T>
523const typename unchecked_factorial_initializer<T>::init unchecked_factorial_initializer<T>::initializer;
524
525
526template <class T, int N>
527inline 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
646template <class T>
647inline 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
778template <class T>
779inline 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
784template <class T>
785inline 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
791template <class T>
792inline 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
798template <class T>
799inline 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
805template <class T>
806inline 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
818template <class T>
819struct 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
833template <class T>
834inline T unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))
835{
836 return 1;
837}
838
839template <class T>
840struct max_factorial
841{
842 BOOST_STATIC_CONSTANT(unsigned, value = 0);
843};
844
845#endif
846
847#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
848template <class T>
849const 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

source code of include/boost/math/special_functions/detail/unchecked_factorial.hpp