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