public XInt Factorial(int N) { var n = (uint)N; var exp2 = (int)(n - MathFun.BitCount(n)); if (n < SmallOddFactorial.Length) { return(new XInt(SmallOddFactorial[n]) << exp2); } if (n >= SmallOddSwing.Length) { this.prime = new Primes(n); this.factors = new Factors(n); } return(this.OddFactorial(n) << exp2); }
//// Swing(n) = OddSwing(n) << (int)MathFun.BitCount(n); private XInt OddSwing(uint n) { if (n < SmallOddSwing.Length) { return(new XInt(SmallOddSwing[n])); } var rootN = MathFun.FloorSqrt(n); this.factors.Init(); this.factors.SetMax(rootN); this.prime.Factorizer(3, rootN, p => { var q = n; while ((q /= p) > 0) { if ((q & 1) == 1) { this.factors.Add(p); } } }); this.factors.SetMax(n / 3); this.prime.Factorizer(rootN + 1, n / 3, p => { if (((n / p) & 1) == 1) { this.factors.Add(p); } }); this.factors.SetMax(n); this.prime.Factorizer(n / 2 + 1, n, p => { this.factors.Add(p); }); return(this.factors.Product()); }
public XInt GetPrimorial(uint min, uint max) { var mem = (int)(0.63 * max / System.Math.Log(max)); var plist = new long[mem]; var size = 0; if (min <= 2) { plist[size++] = 2; } if (min <= 3) { plist[size++] = 3; } var absPos = (int)((min + (min + 1) % 2) / 3 - 1); var index = absPos / BitsPerInt; var bitPos = absPos % BitsPerInt; bool toggle = (bitPos & 1) == 1; var prime = (uint)(5 + 3 * (BitsPerInt * index + bitPos) - (bitPos & 1)); while (prime <= max) { var bitField = this.isComposite[index++] >> bitPos; for (; bitPos < BitsPerInt; bitPos++) { if ((bitField & 1) == 0) { plist[size++] = prime; } prime += (toggle = !toggle) ? 2u : 4u; if (prime > max) { return(MathFun.Product(plist, 0, size)); } bitField >>= 1; } bitPos = 0; } return(XInt.Zero); }
public XInt Product() { this.factors[this.count++] = this.prod; return(MathFun.Product(this.factors, 0, this.count)); }