1: using Xint = System.Numerics.BigInteger;
2: using Xmath = Luschny.Math.MathUtils.Xmath;
3:
4: namespace Luschny.Math.Factorial
5: {
6: public class FactorialBoitenSplit : IFactorialFunction
7: {
8: public FactorialBoitenSplit() { }
9:
10: public string Name
11: {
12: get { return "BoitenSplit "; }
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: if (n < 2) return Xint.One;
24:
25: Xint p = Xint.One;
26: Xint r = Xint.One;
27:
28: int h = 0, shift = 0, k = 1;
29: int log2n = Xmath.FloorLog2(n);
30:
31: while (h != n)
32: {
33: shift += h;
34: h = n >> log2n--;
35: int high = (h & 1) == 1 ? h : h - 1;
36:
37: while (k != high)
38: {
39: k += 2;
40: p *= k;
41: }
42: r *= p;
43: }
44:
45: return r << shift;
46: }
47: }
48: } // endOfFactorialBoitenSplit