public XInt Factorial(int n) { if (n < 0) { throw new ArithmeticException( this.Name + ": " + nameof(n) + " >= 0 required, but was " + n); } this.oddFactNdiv4 = this.oddFactNdiv2 = XInt.One; return(this.OddFactorial(n) << (n - XMath.BitCount(n))); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } 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)); } var sieve = new PrimeSieve(n); var task2 = Task.Factory.StartNew <XInt>(() => { this.results2 = new IAsyncResult[XMath.FloorLog2(n)]; this.swingDelegate2 = Swing2; this.taskCounter2 = 0; var N = n; // -- It is more efficient to add the big swings // -- first and the small ones later! while (N >= Smallswing) { this.results2[this.taskCounter2++] = this.swingDelegate2.BeginInvoke(sieve, N, null, null); N >>= 1; } return(this.RecFactorial2(n)); }); this.results3 = new IAsyncResult[XMath.FloorLog2(n)]; this.swingDelegate3 = Swing3; this.taskCounter3 = 0; var m = n; // -- It is more efficient to add the big swings // -- first and the small ones later! while (m >= Smallswing) { this.results3[this.taskCounter3++] = this.swingDelegate3.BeginInvoke(sieve, m, null, null); m >>= 1; } var task3Result = this.RecFactorial3(n); return((task2.Result * task3Result) << (n - XMath.BitCount(n))); }
public XInt Factorial(int 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.NestedSquare(len) << exp2); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } var rootN = XMath.FloorSqrt(n); var log2N = XMath.FloorLog2(n); var section = new XInt[log2N + 1]; for (var i = 0; i < section.Length; i++) { section[i] = XInt.One; } var sieve = new PrimeSieve(n); var primes = sieve.GetPrimeCollection(3, rootN); foreach (var prime in primes) { int k = 0, m = 0, q = n; do { m += q /= prime; } while (q >= 1); while (m > 0) { if ((m & 1) == 1) { section[k] *= prime; } m = m / 2; k++; } } var j = 2; var low = n; while (low != rootN) { var high = low; low = n / j++; if (low < rootN) { low = rootN; } var primorial = sieve.GetPrimorial(low + 1, high); if (primorial != XInt.One) { int k = 0, m = j - 2; while (m > 0) { if ((m & 1) == 1) { section[k] *= primorial; } m = m / 2; k++; } } } var factorial = section[log2N]; for (var i = log2N - 1; i >= 0; --i) { factorial = XInt.Pow(factorial, 2) * section[i]; } var exp2N = n - XMath.BitCount(n); return(factorial << exp2N); }