1:  package de.luschny.math.factorial;
   2:   
   3:  import de.luschny.math.arithmetic.Xint;
   4:   
   5:  public class FactorialSwingSimple implements IFactorialFunction
   6:  {
   7:   
   8:      public FactorialSwingSimple()
   9:      {
  10:      }
  11:   
  12:      public String getName()
  13:      {
  14:          return "SwingSimple         ";
  15:      }
  16:   
  17:      public Xint factorial(int n)
  18:      {
  19:          if (n < 0)
  20:          {
  21:              throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n);
  22:          }
  23:   
  24:          return recFactorial(n);
  25:      }
  26:   
  27:      private Xint recFactorial(int n)
  28:      {
  29:          if (n < 2)
  30:          {
  31:              return Xint.ONE;
  32:          }
  33:   
  34:          return recFactorial(n / 2).square().multiply(swing(n));
  35:      }
  36:   
  37:      private Xint swing(int n)
  38:      {
  39:          int z;
  40:   
  41:          switch (n % 4)
  42:              {
  43:              case 1:
  44:                  z = n / 2 + 1;
  45:                  break;
  46:              case 2:
  47:                  z = 2;
  48:                  break;
  49:              case 3:
  50:                  z = 2 * (n / 2 + 2);
  51:                  break;
  52:              default:
  53:                  z = 1;
  54:                  break;
  55:              }
  56:   
  57:          Xint b = Xint.valueOf(z);
  58:          z = 2 * (n - ((n + 1) & 1));
  59:   
  60:          for (int i = 1; i <= n / 4; i++, z -= 4)
  61:          {
  62:              b = b.multiply(z).divide(i);
  63:          }
  64:   
  65:          return b;
  66:      }
  67:  } // endOfFactorialSwing