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