public static ulong CeilingSqrt(Int128 a) { if (a.IsNegative) { throw new ArgumentException("argument must not be negative"); } return(UInt128.CeilingSqrt(a.v)); }
public void VFloor2(UInt128 u1, ulong a1, ulong b1, UInt128 c1, UInt128 c2, UInt128 abba, UInt128 ab2, out ulong v1, out ulong 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 = UInt128.Square(t3) - t1 * n; v1 = (ulong)((t2 - UInt128.CeilingSqrt(t4)) / t1); v2 = (ulong)((t2 + (abba << 1) - UInt128.CeilingSqrt((t4 + ((t3 + 1) << 2)))) / t1); }
public UInt128 ProcessRegionManual(int thread, ulong w, ulong a1, ulong b1, UInt128 c1, ulong a2, ulong b2, UInt128 c2) { if (w <= 1) { return(0); } var s = (UInt128)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 = UInt128.Square(t2 + 2) - t4 * n; var u = (ulong)1; while (true) { Debug.Assert((t5 - UInt128.CeilingSqrt(t6)) / t4 == VFloor(u, a1, b1, c1, a2, b2, c2)); #if false s += (t5 - UInt128.CeilingSqrt(t6)) / t4; if (u >= umax) { break; } t5 += t1; t6 += t3; t3 += 8; #else UInt128.Add(ref s, (ulong)((t5 - UInt128.CeilingSqrt(t6)) / t4)); if (u >= umax) { break; } UInt128.Add(ref t5, t1); UInt128.Add(ref t6, ref t3); UInt128.Add(ref t3, 8); #endif ++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 static ulong CeilingSquareRoot(UInt128 a) { return(UInt128.CeilingSqrt(a)); }
public ulong VFloor(UInt128 u, ulong a1, ulong b1, UInt128 c1, ulong a2, ulong b2, UInt128 c2) { return((ulong)((2 * (a1 * b2 + b1 * a2) * (u + c1) - a1 + b1 - UInt128.CeilingSqrt(UInt128.Square(2 * (u + c1) - a1 - b1) - 4 * a1 * b1 * n)) / (4 * a1 * b1) - c2)); }
public ulong UFloor(UInt128 v, ulong a1, ulong b1, UInt128 c1, ulong a2, ulong b2, UInt128 c2) { return((ulong)((2 * (a1 * b2 + b1 * a2) * (v + c2) + a2 - b2 - UInt128.CeilingSqrt(UInt128.Square(2 * (v + c2) - a2 - b2) - 4 * a2 * b2 * n)) / (4 * a2 * b2) - c1)); }
// [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); } }