1: /// -------- ToujoursEnBeta
2: /// Author & Copyright : Peter Luschny
3: /// License: LGPL version 3.0 or (at your option)
4: /// Creative Commons Attribution-ShareAlike 3.0
5: /// Comments mail to: peter(at)luschny.de
6: /// Created: 2010-03-01
7:
8: namespace Sharith.Math.Factorial
9: {
10: using XInt = Sharith.Arithmetic.XInt;
11: using XMath = Sharith.Math.MathUtils.XMath;
12:
13: public class BoitenSplit : IFactorialFunction
14: {
15: public BoitenSplit() { }
16:
17: public string Name
18: {
19: get { return "BoitenSplit "; }
20: }
21:
22: public XInt Factorial(int n)
23: {
24: if (n < 0)
25: {
26: throw new System.ArgumentOutOfRangeException("n",
27: Name + ": n >= 0 required, but was " + n);
28: }
29:
30: if (n < 2) return XInt.One;
31:
32: XInt p = XInt.One;
33: XInt r = XInt.One;
34:
35: int h = 0, shift = 0, k = 1;
36: int log2n = XMath.FloorLog2(n);
37:
38: while (h != n)
39: {
40: shift += h;
41: h = n >> log2n--;
42: int high = (h & 1) == 1 ? h : h - 1;
43:
44: while (k != high)
45: {
46: k += 2;
47: p *= k;
48: }
49: r *= p;
50: }
51:
52: return r << shift;
53: }
54: }
55: } // endOfFactorialBoitenSplit