1:  using Xint = System.Numerics.BigInteger;
   2:  using Xmath = Luschny.Math.MathUtils.Xmath;
   3:   
   4:  namespace Luschny.Math.Factorial
   5:  {
   6:      public class FactorialSquaredDiffProd : IFactorialFunction
   7:      {
   8:          public FactorialSquaredDiffProd() { }
   9:   
  10:          public string Name
  11:          {
  12:              get { return "SquaredDiffProduct  "; }
  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 < 4)
  24:              {
  25:                  return new Xint(n < 2 ? 1 : n == 2 ? 2 : 6);
  26:              }
  27:   
  28:              long h = n / 2, q = h * h;
  29:              long[] f = new long[(int)h];
  30:              f[0] = (n & 1) == 1 ? 2 * q * n : 2 * q;
  31:              int i = 1;
  32:   
  33:              for (int d = 1; d < n - 2; d += 2)
  34:              {
  35:                  f[i++] = q -= d;
  36:              }
  37:   
  38:              return Xmath.Product(f);
  39:          }
  40:      }
  41:  } //endOfFactorialSquaredDiffProd