public BigInteger ProcessRegionManual(int thread, BigInteger w, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2) { if (w <= 1) { return(0); } var s = (BigInteger)0; var umax = (long)w - 1; var t1 = (a1 * b2 + b1 * a2) << 1; var t2 = (c1 << 1) - a1 - b1; var t3 = (t2 << 2) + 12; var t4 = (a1 * b1) << 2; var t5 = t1 * (1 + c1) - a1 + b1 - t4 * c2; var t6 = IntegerMath.Square(t2 + 2) - t4 * n; var store = stores[thread]; var sRep = store.Allocate().Set(0); var t1Rep = store.Allocate().Set(t1); var t3Rep = store.Allocate().Set(t3); var t4Rep = store.Allocate().Set(t4); var t5Rep = store.Allocate().Set(t5); var t6Rep = store.Allocate().Set(t6); var t7Rep = store.Allocate(); var t8Rep = store.Allocate(); var u = (long)1; while (true) { t8Rep.SetUnsignedDifference(t5Rep, t7Rep.SetCeilingSquareRoot(t6Rep, store)) .ModuloWithQuotient(t4Rep, t7Rep); sRep.SetUnsignedSum(sRep, t7Rep); if (u >= umax) { break; } t5Rep.SetUnsignedSum(t5Rep, t1Rep); t6Rep.SetUnsignedSum(t6Rep, t3Rep); t3Rep.SetUnsignedSum(t3Rep, 8); ++u; } s = sRep; store.Release(sRep); store.Release(t1Rep); store.Release(t3Rep); store.Release(t4Rep); store.Release(t6Rep); store.Release(t7Rep); store.Release(t8Rep); Debug.Assert(s == ProcessRegionHorizontal(w, 0, a1, b1, c1, a2, b2, c2)); #if DIAG Console.WriteLine("ProcessRegionManual: s = {0}", s); #endif return(s); }
public void VFloor2(BigInteger u1, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger c2, BigInteger abba, BigInteger ab2, out BigInteger v1, out BigInteger v2) { var uu = (u1 + c1) << 1; var t1 = ab2 << 1; var t2 = abba * uu - a1 + b1 - t1 * c2; var t3 = uu - a1 - b1; var t4 = IntegerMath.Square(t3) - t1 * n; v1 = (t2 - IntegerMath.CeilingSquareRoot(t4)) / t1; v2 = (t2 + (abba << 1) - IntegerMath.CeilingSquareRoot(t4 + ((t3 + 1) << 2))) / t1; }
public ulong ProcessRegionManual(int thread, ulong w, ulong a1, ulong b1, ulong c1, ulong a2, ulong b2, ulong c2) { if (w <= 1) { return(0); } var s = (ulong)0; var umax = w - 1; var t1 = (a1 * b2 + b1 * a2) << 1; var t2 = (c1 << 1) - a1 - b1; var t3 = (t2 << 2) + 12; var t4 = (a1 * b1) << 2; var t5 = t1 * (1 + c1) - a1 + b1 - t4 * c2; var t6 = IntegerMath.Square(t2 + 2) - t4 * n; Debug.Assert(t6 == UInt128.Square(t2 + 2) - t4 * (UInt128)n); var u = (ulong)1; while (true) { Debug.Assert((t5 - IntegerMath.CeilingSquareRoot(t6)) / t4 == VFloor(u, a1, b1, c1, a2, b2, c2)); s += (t5 - IntegerMath.CeilingSquareRoot(t6)) / t4; if (u >= umax) { break; } t5 += t1; t6 += t3; t3 += 8; ++u; } Debug.Assert(s == ProcessRegionHorizontal(w, 0, a1, b1, c1, a2, b2, c2)); #if DIAG Console.WriteLine("ProcessRegionManual: s = {0}", s); #endif return(s); }
public int Evaluate(UInt128 n) { this.n = n; var sum = 0; sqrtn = (long)IntegerMath.FloorSquareRoot(n); kmax = (int)IntegerMath.FloorLog(n, 2); imax = (long)IntegerMath.FloorPower(n, 1, 5) * C1 / C2; xmax = DownToOdd(imax != 0 ? Xi(imax) : sqrtn); xmed = DownToOdd(Math.Min((long)(IntegerMath.FloorPower(n, 2, 7) * C3 / C4), xmax)); var dmax = (long)IntegerMath.Min(n / IntegerMath.Square((UInt128)xmed) + 1, n); mobius = new MobiusOddRangeAdditive((xmax + 2) | 1, threads); divisors = new DivisorOddRangeAdditive((dmax + 2) | 1, threads); xi = new long[imax + 1]; mx = new long[imax + 1]; // Initialize xi. for (var i = 1; i <= imax; i++) { xi[i] = Xi(i); } values = new sbyte[mobiusBatchSize >> 1]; m = new int[mobiusBatchSize >> 1]; m0 = 0; dsums = new ulong[divisorBatchSize >> 1]; d1 = d2 = 1; // Process small x values. for (var x = (long)1; x <= xmed; x += mobiusBatchSize) { var xfirst = x; var xlast = Math.Min(xmed, xfirst + mobiusBatchSize - 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Small(xfirst, xlast); UpdateMx(xfirst, xlast); } // Process medium x values. #if true for (var x = xmed + 2; x <= xmax; x += mobiusBatchSize) { var xfirst = x; var xlast = Math.Min(xmax, xfirst + mobiusBatchSize - 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Medium(xfirst, xlast); UpdateMx(xfirst, xlast); } #else for (var x = xmax; x > xmed; x -= mobiusBatchSize) { var xlast = x; var xfirst = Math.Max(xmed + 2, xlast - mobiusBatchSize + 2); m0 = mobius.GetValuesAndSums(xfirst, xlast + 2, values, m, m0); sum += Pi2Medium(xfirst, xlast); UpdateMx(xfirst, xlast); } #endif // Process large x values. sum += Pi2Large(); // Adjust for final parity of F2. sum -= IntegerMath.Mertens(kmax); // Compute final result. sum &= 3; Debug.Assert((sum & 1) == 0); sum >>= 1; return((sum + (n >= 2 ? 1 : 0)) % 2); }
public BigInteger VFloor(BigInteger u, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2) { return((2 * (a1 * b2 + b1 * a2) * (u + c1) - a1 + b1 - IntegerMath.CeilingSquareRoot(IntegerMath.Square(2 * (u + c1) - a1 - b1) - 4 * a1 * b1 * n)) / (4 * a1 * b1) - c2); }
public BigInteger UFloor(BigInteger v, BigInteger a1, BigInteger b1, BigInteger c1, BigInteger a2, BigInteger b2, BigInteger c2) { return((2 * (a1 * b2 + b1 * a2) * (v + c2) + a2 - b2 - IntegerMath.CeilingSquareRoot(IntegerMath.Square(2 * (v + c2) - a2 - b2) - 4 * a2 * b2 * n)) / (4 * a2 * b2) - c1); }
public BigInteger UTan(BigInteger ab1, BigInteger abba, BigInteger ab2, BigInteger a3b3, BigInteger c1) { return((ab1 + IntegerMath.FloorSquareRoot(IntegerMath.Square(abba + ab2) * n / a3b3) - (c1 << 1)) / 2); }