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); }
private static XInt Swing3(PrimeSieve sieve, int n) { var primorial = Task.Factory.StartNew <XInt>(() => { var start = sieve.NextPrime(n / 2); start = sieve.NextPrime(start); return(sieve.GetPrimorial(start, n, 2)); }); var count = 0; var rootN = XMath.FloorSqrt(n); var startPrime = sieve.NextPrime(rootN); startPrime = sieve.NextPrime(startPrime); var aPrimes = sieve.GetPrimeCollectionEveryOther(5, rootN); var bPrimes = sieve.GetPrimeCollectionEveryOther(startPrime, n / 3); var primeList = new int[aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes]; foreach (var prime in aPrimes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { primeList[count++] = p; } } foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) { primeList[count++] = prime; } var primeProduct = XMath.Product(primeList, 0, count); return(primeProduct * primorial.Result); }
XInt Swing(int n) { if (n < 33) { return(SmallOddSwing[n]); } var primorial = Task.Factory.StartNew <XInt>(() => this.sieve.GetPrimorial(n / 2 + 1, n)); var count = 0; var rootN = XMath.FloorSqrt(n); var aPrimes = this.sieve.GetPrimeCollection(3, rootN); var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); var piN = aPrimes.NumberOfPrimes + bPrimes.NumberOfPrimes; var primeList = new int[piN]; foreach (var prime in aPrimes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { primeList[count++] = p; } } foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) { primeList[count++] = prime; } var primeProduct = XMath.Product(primeList, 0, count); return(primeProduct * primorial.Result); }
private XInt Swing(int n) { if (n < 33) { return(SmallOddSwing[n]); } int count = 0, rootN = XMath.FloorSqrt(n); var aPrimes = this.sieve.GetPrimeCollection(3, rootN); var bPrimes = this.sieve.GetPrimeCollection(rootN + 1, n / 3); foreach (var prime in aPrimes) { int q = n, p = 1; while ((q /= prime) > 0) { if ((q & 1) == 1) { p *= prime; } } if (p > 1) { this.primeList[count++] = p; } } foreach (var prime in bPrimes.Where(prime => ((n / prime) & 1) == 1)) { this.primeList[count++] = prime; } var primorial = this.sieve.GetPrimorial(n / 2 + 1, n); return(primorial * XMath.Product(this.primeList, 0, count)); }
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); }