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;
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
    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");
        }
    }
Exemple #4
0
//        [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));
 }