1: using Xint = System.Numerics.BigInteger;
2:
3:
4: namespace Luschny.Math.Factorial
5: {
6: public class FactorialHyper : IFactorialFunction
7: {
8: public FactorialHyper() { }
9:
10: public string Name
11: {
12: get { return "Hyper "; }
13: }
14:
15: private bool nostart;
16: private long s, k, a;
17:
18: public Xint Factorial(int n)
19: {
20: if (n < 0)
21: {
22: throw new System.ArgumentOutOfRangeException("n",
23: Name + ": n >= 0 required, but was " + n);
24: }
25:
26: nostart = false;
27: int h = n / 2;
28: s = h + 1;
29: k = s + h;
30: a = (n & 1) == 1 ? k : 1;
31: if ((h & 1) == 1) a = -a;
32: k += 4;
33:
34: return HyperFact(h + 1) << h;
35: }
36:
37: private Xint HyperFact(int l)
38: {
39: if (l > 1)
40: {
41: int m = l >> 1;
42: return HyperFact(m) * HyperFact(l - m);
43: }
44:
45: if (nostart)
46: {
47: s -= k -= 4;
48: return (Xint) s;
49: }
50: else
51: {
52: nostart = true;
53: return (Xint) a;
54: }
55: }
56: }
57: } // endOfFactorialHyper