public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.sieve = new PrimeSieve(n); return(this.RecFactorial(n)); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } var log2N = XMath.FloorLog2(n); var j = log2N; var hN = n; this.primeList = new int[log2N][]; this.listLength = new int[log2N]; this.bound = new int[log2N]; this.tower = new int[log2N + 1]; while (true) { this.tower[j] = hN; if (hN == 1) { break; } this.bound[--j] = hN / 3; var pLen = hN < 4 ? 6 : (int)(2.0 * (XMath.FloorSqrt(hN) + (double)hN / (XMath.Log2(hN) - 1))); this.primeList[j] = new int[pLen]; hN >>= 1; } this.tower[0] = 2; this.PrimeFactors(n); var init = this.listLength[0] == 0 ? 1 : 3; var oddFactorial = new XInt(init); var results = new XInt[log2N]; Parallel.For(1, log2N, i => results[i] = XMath.Product(this.primeList[i], 0, this.listLength[i]) ); for (var i = 1; i < log2N; i++) { oddFactorial = XInt.Pow(oddFactorial, 2); oddFactorial = oddFactorial * results[i]; } return(oddFactorial << (n - XMath.BitCount(n))); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.cache = new Dictionary <int, CachedPrimorial>(); this.sieve = new PrimeSieve(n); var pLen = (int)(2.0 * (XMath.FloorSqrt(n) + (double)n / (XMath.Log2(n) - 1))); this.primeList = new int[pLen]; var exp2 = n - XMath.BitCount(n); return(this.RecFactorial(n) << exp2); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.sieve = new PrimeSieve(n); var log2N = XMath.FloorLog2(n); SwingDelegate swingDelegate = this.Swing; var results = new IAsyncResult[log2N]; int h = 0, shift = 0, taskCounter = 0; // -- It is more efficient to add the big intervals // -- first and the small ones later! while (h != n) { shift += h; h = n >> log2N--; if (h > 2) { results[taskCounter++] = swingDelegate.BeginInvoke(h, null, null); } } XInt p = XInt.One, r = XInt.One, rl = XInt.One; for (var i = 0; i < taskCounter; i++) { var t = rl * swingDelegate.EndInvoke(results[i]); p = p * t; rl = r; r = r * p; } return(r << shift); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } var sieve = new PrimeSieve(n); this.results = new IAsyncResult[XMath.FloorLog2(n)]; this.swingDelegate = Swing; this.taskCounter = 0; var N = n; // -- It is more efficient to add the big swings // -- first and the small ones later! while (N >= Smallswing) { this.results[this.taskCounter++] = this.swingDelegate.BeginInvoke(sieve, N, null, null); N >>= 1; } return(this.RecFactorial(n) << (n - XMath.BitCount(n))); }
public XInt Factorial(int n) { if (n < 0) { throw new System.ArgumentOutOfRangeException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } if (n < 20) { return(XMath.Factorial(n)); } var lgN = XMath.FloorLog2(n); var piN = 2 + (15 * n) / (8 * (lgN - 1)); this.primeList = new int[piN]; this.multiList = new int[piN]; var len = this.PrimeFactors(n); var exp2 = n - XMath.BitCount(n); return(this.RepeatedSquare(len, 1) << exp2); }