void DoTest(Candidate cand, int n, bool showFullValue, bool verbose) { this.watch.Reset(); this.watch.Start(); XInt nFact = cand.GetValue(n); this.watch.Stop(); int checksum = nFact.GetHashCode(); var ms = this.watch.ElapsedMilliseconds; var eddms = XMath.ExactDecimalDigitsPerMillisecond(n, ms); var res = new Result(cand, ms, checksum, eddms); cand.Performance[n] = res; if (verbose) { this.winsole.WriteRed(string.Format( // "\nSUMMARY: Computed the factorial " "\n{0}! = {1}\nAlgorithm used: {2}\nCheckSum: <{3:X}>\nComputation in {4:D} ms.\nDecimal digits per ms {5}.\n", n, XMath.AsymptFactorial(n), cand.Name, checksum, ms, eddms)); } if (showFullValue) { this.winsole.Write(nl + "Now converting to string. Note: It takes longer to convert than to compute!" + nl + nl); this.winsole.WriteLine(nFact.ToString()); } }
public void SanityCheck(int length) { bool ok = true; for (int n = 0; n < length; n++) { XInt r = Candidate.Reference.GetValue(n); foreach (Candidate cand in Candidate.Sanity) { XInt t = cand.GetValue(n); if (!t.Equals(r)) { this.winsole.WriteLine(string.Format( "\n{0}({1}) failed!", cand.Name.Trim(), n)); ok = false; } } if ((n % 10) == 0) { this.winsole.WriteFlush(" . "); } if ((n % 150) == 149) { this.winsole.WriteLine(); } } this.winsole.Write("\nWell, some values will" + (ok ? " " : " not ") + "give correct results " + (ok ? ";-)\n" : "~:(\n")); }
private XInt RecFactorial(int n) { if (n < 2) { return(XInt.One); } return(XInt.Pow(this.RecFactorial(n / 2), 2) * this.Swing(n)); }
static XInt OddSwing(int n, XInt oddFactNdiv4) { if (n < Smallswing) return SmallOddSwing[n]; var len = (n - 1) / 4; if ((n % 4) != 2) len++; var high = n - ((n + 1) & 1); return Product(high, len) / oddFactNdiv4; }
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 < 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)); }
private XInt RecFactorial3(int n) { if (n < 2) { return(XInt.One); } var recFact = this.RecFactorial3(n / 2); var sqrFact = XInt.Pow(recFact, 2); var swing = n < Smallswing ? SmallOddSwing3[n] : this.swingDelegate3.EndInvoke(this.results3[--this.taskCounter3]); return(sqrFact * swing); }
static XInt OddSwing(int n, XInt oddFactNdiv4) { if (n < Smallswing) { return(SmallOddSwing[n]); } var len = (n - 1) / 4; if ((n % 4) != 2) { len++; } var high = n - ((n + 1) & 1); return(Product(high, len) / oddFactNdiv4); }
public XInt Factorial(int n) { if (n < 20) { return(XMath.Factorial(n)); } this.sieve = new PrimeSieve(n); var log2N = XMath.FloorLog2(n); var source = new int[log2N]; int h = 0, shift = 0, length = 0; // -- It is more efficient to add the big intervals // -- first and the small ones later! Is it? while (h != n) { shift += h; h = n >> log2N--; if (h > 2) { source[length++] = h; } } var results = new XInt[length]; Parallel.For(0, length, currentIndex => results[currentIndex] = this.Swing(source[currentIndex]) ); XInt p = XInt.One, r = XInt.One, rl = XInt.One; for (var i = 0; i < length; i++) { var t = rl * results[i]; p = p * t; rl = r; r = r * p; } return(r << shift); }
private XInt OddFactorial(int n) { XInt oddFact; if (n < Smallfact) { oddFact = SmallOddFactorial[n]; } else { var sqrOddFact = this.OddFactorial(n / 2); var ndiv4 = n / 4; var oddFactNd4 = ndiv4 < Smallfact ? SmallOddFactorial[ndiv4] : this.oddFactNdiv4; oddFact = XInt.Pow(sqrOddFact, 2) * OddSwing(n, oddFactNd4); } this.oddFactNdiv4 = this.oddFactNdiv2; this.oddFactNdiv2 = oddFact; return(oddFact); }
public XInt Factorial(int n) { if (n < 20) { return XMath.Factorial(n); } this.sieve = new PrimeSieve(n); var log2N = XMath.FloorLog2(n); var source = new int[log2N]; int h = 0, shift = 0, length = 0; // -- It is more efficient to add the big intervals // -- first and the small ones later! Is it? while (h != n) { shift += h; h = n >> log2N--; if (h > 2) { source[length++] = h; } } var results = new XInt[length]; Parallel.For(0, length, currentIndex => results[currentIndex] = this.Swing(source[currentIndex]) ); XInt p = XInt.One, r = XInt.One, rl = XInt.One; for (var i = 0; i < length; i++) { var t = rl * results[i]; p = p * t; rl = r; r = r * p; } return r << shift; }
private XInt NestedSquare(int len) { if (len == 0) { return(XInt.One); } var i = 0; var mult = this.multiList[0]; while (mult > 1) { if ((mult & 1) == 1) // is mult odd ? { this.primeList[len++] = this.primeList[i]; } this.multiList[i++] = mult >> 1; mult = this.multiList[i]; } return(XMath.Product(this.primeList, i, len - i) * XInt.Pow(this.NestedSquare(i), 2)); }
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; }
private static XInt BigRecProduct(XInt[] s, int n, int m) { if (n > m) { return XInt.One; } if (n == m) { return s[n]; } int k = (n + m) >> 1; return BigRecProduct(s, n, k) * BigRecProduct(s, k + 1, m); }
public static XInt Product(XInt[] a, int start, int len) { int n = len - 1; if (len > ParallelThreshold) { var task = Task.Factory.StartNew<XInt>(() => { return BigRecProduct(a, start + n / 2 + 1, start + n); }); var left = BigRecProduct(a, start, start + n / 2); return left * task.Result; } return BigRecProduct(a, start, n); }
private XInt OddFactorial(int n) { XInt oddFact; if (n < Smallfact) { oddFact = SmallOddFactorial[n]; } else { var sqrOddFact = this.OddFactorial(n / 2); var ndiv4 = n / 4; var oddFactNd4 = ndiv4 < Smallfact ? SmallOddFactorial[ndiv4] : this.oddFactNdiv4; oddFact = XInt.Pow(sqrOddFact, 2) * OddSwing(n, oddFactNd4); } this.oddFactNdiv4 = this.oddFactNdiv2; this.oddFactNdiv2 = oddFact; return oddFact; }
public static XInt Product(XInt[] a) { return BigRecProduct(a, 0, a.Length - 1); }
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); }