1:  using Xint = System.Numerics.BigInteger;
   2:   
   3:   
   4:  namespace Luschny.Math.Factorial
   5:  {
   6:      public class FactorialHyper : IFactorialFunction
   7:      {
   8:          public FactorialHyper() { }
   9:   
  10:          public string Name
  11:          {
  12:              get { return "Hyper               "; }
  13:          }
  14:   
  15:          private bool nostart;
  16:          private long s, k, a;
  17:   
  18:          public Xint Factorial(int n)
  19:          {
  20:              if (n < 0)
  21:              {
  22:                  throw new System.ArgumentOutOfRangeException("n",
  23:                  Name + ": n >= 0 required, but was " + n);
  24:              }
  25:   
  26:              nostart = false;
  27:              int h = n / 2;
  28:              s = h + 1;
  29:              k = s + h;
  30:              a = (n & 1) == 1 ? k : 1;
  31:              if ((h & 1) == 1) a = -a;
  32:              k += 4;
  33:   
  34:              return HyperFact(h + 1) << h;
  35:          }
  36:   
  37:          private Xint HyperFact(int l)
  38:          {
  39:              if (l > 1)
  40:              {
  41:                  int m = l >> 1;
  42:                  return HyperFact(m) * HyperFact(l - m);
  43:              }
  44:   
  45:              if (nostart)
  46:              {
  47:                  s -= k -= 4;
  48:                  return (Xint) s;
  49:              }
  50:              else
  51:              {
  52:                  nostart = true;
  53:                  return (Xint) a;
  54:              }
  55:          }
  56:      }
  57:  } // endOfFactorialHyper