1:  package de.luschny.math.factorial;
   2:   
   3:  import de.luschny.math.arithmetic.Xint;
   4:   
   5:  public class FactorialHyper implements IFactorialFunction
   6:  {
   7:   
   8:      public FactorialHyper()
   9:      {
  10:      }
  11:   
  12:      public String getName()
  13:      {
  14:          return "Hyper             ";
  15:      }
  16:   
  17:      private boolean nostart;
  18:      private long S, K, A;
  19:   
  20:      public Xint factorial(int n)
  21:      {
  22:          if (n < 0)
  23:          {
  24:              throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n);
  25:          }
  26:   
  27:          nostart = false;
  28:          int h = n / 2;
  29:          S = h + 1;
  30:          K = S + h;
  31:          A = (n & 1) == 1 ? K : 1;
  32:          if ((h & 1) == 1)
  33:          {
  34:              A = -A;
  35:          }
  36:          K += 4;
  37:   
  38:          return hyperFact(h + 1).shiftLeft(h);
  39:      }
  40:   
  41:      private Xint hyperFact(int l)
  42:      {
  43:          if (l > 1)
  44:          {
  45:              int m = l / 2;
  46:              return hyperFact(m).multiply(hyperFact(l - m));
  47:          }
  48:   
  49:          if (nostart)
  50:          {
  51:              S -= K -= 4;
  52:              return Xint.valueOf(S);
  53:          }
  54:   
  55:          nostart = true;
  56:          return Xint.valueOf(A);
  57:      }
  58:  } // endOfFactorialHyper