private void UpdateMxLarge(long x1, long x2, int[] r) { for (var l = 0; l < r.Length; l++) { var i = r[l]; var x = niLarge[i]; var sqrt = (long)UInt128.FloorSqrt(x); var xover = (long)UInt128.Min((ulong)(sqrt * C3 / C4), x); xover = (long)(x / (x / (ulong)xover)); var s = (Int128)0; var jmin = UpToOdd(Math.Max(imax / i + 1, (long)UInt128.Min((ulong)xover + 1, x / ((ulong)x2 + 1) + 1))); var jmax = DownToOdd((long)UInt128.Min((ulong)xover, x / (ulong)x1)); s += JSumLarge1(x, jmin, ref jmax, x1); s += JSumLarge2(x, jmin, jmax, x1); var kmin = Math.Max(1, x1); var kmax = (long)UInt128.Min(x / (ulong)xover - 1, (ulong)x2); s += KSumLarge1Mu(x, kmin, ref kmax, x1); //s += KSumLarge1M(x, kmin, ref kmax, x1); s += KSumLarge2(x, kmin, kmax, x1); mx[i] -= s; } }
private UInt128 EvaluateInternal(UInt128 n, UInt128 x0, UInt128 xmax) { this.n = n; x0 = T1(x0 + 1); xmax = T1(xmax); if (x0 > xmax) { return(0); } var ymin = YFloor(xmax); var xmin = UInt128.Max(x0, UInt128.Min(T1(C1 * UInt128.CeilingCbrt(2 * n)), xmax)); #if DIAG Console.WriteLine("n = {0}, xmin = {1}, xmax = {2}", n, xmin, xmax); #endif var s = (UInt128)0; var a2 = (ulong)1; var x2 = xmax; var y2 = ymin; var c2 = a2 * x2 + y2; while (true) { var a1 = a2 + 1; var x4 = YTan(a1); var y4 = YFloor(x4); var c4 = a1 * x4 + y4; var x5 = x4 + 1; var y5 = YFloor(x5); var c5 = a1 * x5 + y5; if (x4 <= xmin) { break; } s += Triangle(c4 - c2 - x0) - Triangle(c4 - c2 - x5) + Triangle(c5 - c2 - x5); if (threads == 0) { s += ProcessRegion(0, (ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2); while (stack.Count > 0) { var r = stack.Pop(); s += ProcessRegion(0, r.w, r.h, r.a1, r.b1, r.c1, r.a2, r.b2, r.c2); } } else { Enqueue(new Region((ulong)(a1 * x2 + y2 - c5), (ulong)(a2 * x5 + y5 - c2), a1, 1, c5, a2, 1, c2)); } a2 = a1; x2 = x4; y2 = y4; c2 = c4; } s += (xmax - x0 + 1) * ymin + Triangle(xmax - x0); var rest = x2 - x0; s -= y2 * rest + a2 * Triangle(rest); xmanual = x2; return(s); }
private void SetValue(Node <T> node, UInt128 start, UInt128 length, UInt128 ip_from, UInt128 ip_to, T value) { if (ip_from > ip_to) { throw new ArgumentException("Invalid range", nameof(ip_from)); } if (node != null) { UInt128 l_start = start; UInt128 l_end = l_start + length - 1; if (l_start <= ip_from && l_end >= ip_from) { if (l_start == ip_from && l_end <= ip_to) { node.LValue = value; node.LPtr = null; } else { if (node.LValue != null) { node.LPtr = new Node <T> { LValue = node.LValue, LPtr = null, RValue = node.LValue, RPtr = null }; node.LValue = default; } SetValue(node.LPtr, l_start, length >> 1, ip_from, UInt128.Min(l_end, ip_to), value); } } UInt128 r_start = start + length; UInt128 r_end = r_start + length - 1; if (r_start <= ip_to && r_end >= ip_to) { if (r_start >= ip_from && r_end == ip_to) { node.RValue = value; node.RPtr = null; } else { if (node.RValue != null) { node.RPtr = new Node <T> { LValue = node.RValue, LPtr = null, RValue = node.RValue, RPtr = null }; node.RValue = default; } SetValue(node.RPtr, r_start, length >> 1, UInt128.Max(r_start, ip_from), ip_to, value); } } } else { throw new IPFilterException("Can't find node. IPFilter seems to be corrupted"); } }
// [DataRow(uint.MaxValue, uint.MaxValue)] // [DataRow(ulong.MaxValue, ulong.MaxValue)] public void UInt128Test(ulong factorMax, ulong modulusMax) { var random = new MersenneTwister(0).Create <ulong>(); for (int i = 0; i < 10000; i++) { var n = random.Next(modulusMax - 1) + 1; var a = random.Next(factorMax) % n; var b = random.Next(factorMax) % n; var c = random.Next(factorMax) % n; var d = random.Next(factorMax) % n; var s = (int)(b % 32); var value = (UInt128)0; Assert.AreEqual((BigInteger)a << s, (UInt128)a << s); Assert.AreEqual((BigInteger)a >> s, (UInt128)a >> s); Assert.AreEqual((BigInteger)a & b, (UInt128)a & b); Assert.AreEqual((BigInteger)a & b, a & (UInt128)b); Assert.AreEqual((BigInteger)a & b, (UInt128)a & (UInt128)b); Assert.AreEqual((BigInteger)a | b, (UInt128)a | b); Assert.AreEqual((BigInteger)a | b, a | (UInt128)b); Assert.AreEqual((BigInteger)a | b, (UInt128)a | (UInt128)b); Assert.AreEqual((BigInteger)a ^ b, (UInt128)a ^ b); Assert.AreEqual((BigInteger)a ^ b, a ^ (UInt128)b); Assert.AreEqual((BigInteger)a ^ b, (UInt128)a ^ (UInt128)b); if (a <= long.MaxValue) { Assert.AreEqual(~(BigInteger)a, (long)~(UInt128)a); } Assert.AreEqual((BigInteger)a + b, (UInt128)a + b); Assert.AreEqual((BigInteger)a + b, a + (UInt128)b); Assert.AreEqual((BigInteger)a + b, (UInt128)a + (UInt128)b); Assert.AreEqual(((BigInteger)a * n + (BigInteger)b * n) % ((BigInteger)1 << 128), (UInt128)a * n + (UInt128)b * n); if (a >= b) { Assert.AreEqual((BigInteger)a - b, (UInt128)a - b); Assert.AreEqual((BigInteger)a - b, a - (UInt128)b); Assert.AreEqual((BigInteger)a - b, (UInt128)a - (UInt128)b); Assert.AreEqual((BigInteger)a * n - (BigInteger)b * n, (UInt128)a * n - (UInt128)b * n); } Assert.AreEqual(+(BigInteger)a, +(Int128)a); value = a; Assert.AreEqual((BigInteger)a + 1, ++value); value = a; Assert.AreEqual((BigInteger)a, value++); value = (UInt128)a * b; Assert.AreEqual((BigInteger)a * b + 1, ++value); value = (UInt128)a * b; Assert.AreEqual((BigInteger)a * b, value++); if (a > 0) { value = a; Assert.AreEqual((BigInteger)a - 1, --value); value = a; Assert.AreEqual((BigInteger)a, value--); } if (a > 0 && b > 0) { value = (UInt128)a * b; Assert.AreEqual((BigInteger)a * b - 1, --value); value = (UInt128)a * b; Assert.AreEqual((BigInteger)a * b, value--); } if (n <= uint.MaxValue) { Assert.AreEqual((BigInteger)a * n, (UInt128)a * (uint)n); Assert.AreEqual((BigInteger)b * n, (UInt128)b * (uint)n); Assert.AreEqual((BigInteger)a * b * n % ((BigInteger)1 << 128), (UInt128)a * b * (uint)n); Assert.AreEqual((BigInteger)n * a, (uint)n * (UInt128)a); Assert.AreEqual((BigInteger)n * b, (uint)n * (UInt128)b); Assert.AreEqual((BigInteger)n * a * b % ((BigInteger)1 << 128), (uint)n * ((UInt128)a * (UInt128)b)); } Assert.AreEqual((BigInteger)a * b, a * (UInt128)b); Assert.AreEqual((BigInteger)a * b, (UInt128)a * b); Assert.AreEqual((BigInteger)a * b, a * (UInt128)b); Assert.AreEqual((BigInteger)a * b, (UInt128)a * (UInt128)b); if (b > 0) { Assert.AreEqual((BigInteger)a % b, (UInt128)a % b); Assert.AreEqual((BigInteger)a % b, a % (UInt128)b); Assert.AreEqual((BigInteger)a % b, (UInt128)a % (UInt128)b); } Assert.AreEqual((BigInteger)a * b % n, (UInt128)a * b % n); Assert.AreEqual((BigInteger)a * b % n, a * (UInt128)b % n); Assert.AreEqual((BigInteger)a * b % n, (UInt128)a * (UInt128)b % (UInt128)n); if (c > 0 && d > 0) { Assert.AreEqual((BigInteger)a * b / ((BigInteger)c * d), (UInt128)a * (UInt128)b / ((UInt128)c * (UInt128)d)); Assert.AreEqual((BigInteger)a * b % ((BigInteger)c * d), (UInt128)a * (UInt128)b % ((UInt128)c * (UInt128)d)); } if (b > 0) { Assert.AreEqual((BigInteger)a / b, (UInt128)a / b); Assert.AreEqual((BigInteger)a / b, a / (UInt128)b); Assert.AreEqual((BigInteger)a / b, (UInt128)a / (UInt128)b); } Assert.AreEqual((BigInteger)a * b / n, (UInt128)a * b / n); Assert.AreEqual((BigInteger)a * b / n, a * (UInt128)b / n); Assert.AreEqual((BigInteger)a * b / n, (UInt128)a * (UInt128)b / (UInt128)n); Assert.AreEqual((BigInteger)a < b, (UInt128)a < b); Assert.AreEqual((BigInteger)a < b, a < (UInt128)b); Assert.AreEqual((BigInteger)a < b, (UInt128)a < (UInt128)b); Assert.AreEqual((BigInteger)a <= b, (UInt128)a <= b); Assert.AreEqual((BigInteger)a <= b, a <= (UInt128)b); Assert.AreEqual((BigInteger)a <= b, (UInt128)a <= (UInt128)b); Assert.AreEqual((BigInteger)a > b, (UInt128)a > b); Assert.AreEqual((BigInteger)a > b, a > (UInt128)b); Assert.AreEqual((BigInteger)a > b, (UInt128)a > (UInt128)b); Assert.AreEqual((BigInteger)a >= b, (UInt128)a >= b); Assert.AreEqual((BigInteger)a >= b, a >= (UInt128)b); Assert.AreEqual((BigInteger)a >= b, (UInt128)a >= (UInt128)b); Assert.AreEqual((BigInteger)a == b, (UInt128)a == b); Assert.AreEqual((BigInteger)a == b, a == (UInt128)b); Assert.AreEqual((BigInteger)a == b, (UInt128)a == (UInt128)b); Assert.AreEqual((BigInteger)a != b, (UInt128)a != b); Assert.AreEqual((BigInteger)a != b, a != (UInt128)b); Assert.AreEqual((BigInteger)a != b, (UInt128)a != (UInt128)b); Assert.AreEqual((BigInteger)a * a, UInt128.Square(a)); Assert.AreEqual(BigInteger.Abs(a), UInt128.Abs(a)); Assert.AreEqual(BigInteger.Abs((BigInteger)a * b), UInt128.Abs((UInt128)a * b)); Assert.AreEqual(BigInteger.Min(a, b), UInt128.Min(a, b)); Assert.AreEqual(BigInteger.Min((BigInteger)a * n, (BigInteger)b * n), UInt128.Min((UInt128)a * n, (UInt128)b * n)); Assert.AreEqual(BigInteger.Max(a, b), UInt128.Max(a, b)); Assert.AreEqual(BigInteger.Max((BigInteger)a * n, (BigInteger)b * n), UInt128.Max((UInt128)a * n, (UInt128)b * n)); for (var j = 0; j < 2; j++) { var m = UInt128.Abs(j == 0 ? (UInt128)a * (UInt128)b : (UInt128)n * (UInt128)n); var floorsqrt = UInt128.FloorSqrt(m); Assert.IsTrue((BigInteger)floorsqrt * floorsqrt <= m && (BigInteger)(floorsqrt + 1) * (floorsqrt + 1) > m); var ceilingsqrt = UInt128.CeilingSqrt(m); Assert.IsTrue((BigInteger)(ceilingsqrt - 1) * (ceilingsqrt - 1) < m && (BigInteger)ceilingsqrt * ceilingsqrt >= m); } for (var j = 0; j < 2; j++) { var m = j == 0 ? (UInt128)a * (UInt128)b : (UInt128)BigInteger.Pow((BigInteger)Math.Floor(Math.Pow((double)((BigInteger)a * b), (double)1 / 3)), 3); var floorcbrt = UInt128.FloorCbrt(m); Assert.IsTrue((BigInteger)floorcbrt * floorcbrt * floorcbrt <= m && (BigInteger)(floorcbrt + 1) * (floorcbrt + 1) * (floorcbrt + 1) > m); var ceilingcbrt = UInt128.CeilingCbrt(m); Assert.IsTrue((BigInteger)(ceilingcbrt - 1) * (ceilingcbrt - 1) * (ceilingcbrt - 1) < m && (BigInteger)ceilingcbrt * ceilingcbrt * ceilingcbrt >= m); } Assert.AreEqual(BigInteger.GreatestCommonDivisor((BigInteger)a, (BigInteger)b), UInt128.GreatestCommonDivisor((UInt128)a, (UInt128)b)); Assert.AreEqual(BigInteger.GreatestCommonDivisor((BigInteger)a * b, (BigInteger)c * d), UInt128.GreatestCommonDivisor((UInt128)a * b, (UInt128)c * d)); Assert.AreEqual(0, 0); } }
public static UInt128 Min(UInt128 a, UInt128 b) { return(UInt128.Min(a, b)); }