1: using Xint = System.Numerics.BigInteger;
2:
3:
4: namespace Luschny.Math.Factorial
5: {
6: public class FactorialSwingSimple : IFactorialFunction
7: {
8: public FactorialSwingSimple() { }
9:
10: public string Name
11: {
12: get { return "SwingSimple "; }
13: }
14:
15: public Xint Factorial(int n)
16: {
17: if (n < 0)
18: {
19: throw new System.ArgumentOutOfRangeException("n",
20: Name + ": n >= 0 required, but was " + n);
21: }
22:
23: return RecFactorial(n);
24: }
25:
26: private Xint RecFactorial(int n)
27: {
28: if (n < 2) return Xint.One;
29:
30: return Xint.Pow(RecFactorial(n / 2),2) * Swing(n);
31: }
32:
33: private static Xint Swing(int n)
34: {
35: int z;
36:
37: switch (n % 4)
38: {
39: case 1: z = n / 2 + 1; break;
40: case 2: z = 2; break;
41: case 3: z = 2 * (n / 2 + 2); break;
42: default: z = 1; break;
43: }
44:
45: Xint b = new Xint(z);
46: z = 2 * (n - ((n + 1) & 1));
47:
48: for (int i = 1; i <= n / 4; i++, z -= 4)
49: {
50: b = (b * z) / i;
51: }
52:
53: return b;
54: }
55: }
56: } // endOfFactorialSwingSimple