`   1:  package de.luschny.math.factorial;`
`   2:   `
`   3:  import de.luschny.math.arithmetic.Xint;`
`   4:   `
`   5:  public class FactorialSplit implements IFactorialFunction`
`   6:  {`
`   7:   `
`   8:      public FactorialSplit()`
`   9:      {`
`  10:      }`
`  11:   `
`  12:      public String getName()`
`  13:      {`
`  14:          return "Split             ";`
`  15:      }`
`  16:   `
`  17:      private long N;`
`  18:   `
`  19:      public Xint factorial(int n)`
`  20:      {`
`  21:          if (n < 0)`
`  22:          {`
`  23:              throw new ArithmeticException("Factorial: n has to be >= 0, but was " + n);`
`  24:          }`
`  25:   `
`  26:          if (n < 2)`
`  27:          {`
`  28:              return Xint.ONE;`
`  29:          }`
`  30:   `
`  31:          Xint p = Xint.ONE;`
`  32:          Xint r = Xint.ONE;`
`  33:          N = 1;`
`  34:   `
`  35:          // log2n = floor(log2(n));`
`  36:          int log2n = 31 - Integer.numberOfLeadingZeros(n);`
`  37:          int h = 0, shift = 0, high = 1;`
`  38:   `
`  39:          while (h != n)`
`  40:          {`
`  41:              shift += h;`
`  42:              h = n >>> log2n--;`
`  43:              int len = high;`
`  44:              high = (h & 1) == 1 ? h : h - 1;`
`  45:              len = (high - len) / 2;`
`  46:   `
`  47:              if (len > 0)`
`  48:              {`
`  49:                  p = p.multiply(product(len));`
`  50:                  r = r.multiply(p);`
`  51:              }`
`  52:          }`
`  53:          return r.shiftLeft(shift);`
`  54:      }`
`  55:   `
`  56:      private Xint product(int n)`
`  57:      {`
`  58:          int m = n / 2;`
`  59:          if (m == 0)`
`  60:          {`
`  61:              return Xint.valueOf(N += 2);`
`  62:          }`
`  63:          if (n == 2)`
`  64:          {`
`  65:              return Xint.valueOf((N += 2) * (N += 2));`
`  66:          }`
`  67:          return product(n - m).multiply(product(m));`
`  68:      }`
`  69:  } // endOfFactorialSplitRecursive`