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