// [DataRow(int.MaxValue, int.MaxValue)] // [DataRow(uint.MaxValue, uint.MaxValue)] // [DataRow(long.MaxValue, long.MaxValue)] public void Int128Test(long factorMax, long modulusMax) { var random = new MersenneTwister(0).Create <long>(); for (int i = 0; i < 10000; i++) { var n = random.Next(modulusMax - 1) + 1; var a = random.Next(factorMax) % n - factorMax / 2; var b = random.Next(factorMax) % n - factorMax / 2; var s = (int)(Math.Abs(b) % 32); var value = (Int128)0; Assert.AreEqual((BigInteger)a << s, (Int128)a << s); Assert.AreEqual((BigInteger)a >> s, (Int128)a >> s); Assert.AreEqual((BigInteger)a & b, (Int128)a & b); Assert.AreEqual((BigInteger)a & b, a & (Int128)b); Assert.AreEqual((BigInteger)a & b, (Int128)a & (Int128)b); Assert.AreEqual((BigInteger)a | b, (Int128)a | b); Assert.AreEqual((BigInteger)a | b, a | (Int128)b); Assert.AreEqual((BigInteger)a | b, (Int128)a | (Int128)b); Assert.AreEqual((BigInteger)a ^ b, (Int128)a ^ b); Assert.AreEqual((BigInteger)a ^ b, a ^ (Int128)b); Assert.AreEqual((BigInteger)a ^ b, (Int128)a ^ (Int128)b); if (a <= long.MaxValue) { Assert.AreEqual(~(BigInteger)a, (long)~(Int128)a); } Assert.AreEqual((BigInteger)a + b, (Int128)a + b); Assert.AreEqual((BigInteger)a + b, a + (Int128)b); Assert.AreEqual((BigInteger)a + b, (Int128)a + (Int128)b); Assert.AreEqual(((BigInteger)a * n + (BigInteger)b * n) % ((BigInteger)1 << 128), (Int128)a * n + (Int128)b * n); Assert.AreEqual((BigInteger)a - b, (Int128)a - b); Assert.AreEqual((BigInteger)a - b, a - (Int128)b); Assert.AreEqual((BigInteger)a - b, (Int128)a - (Int128)b); Assert.AreEqual(((BigInteger)a * n - (BigInteger)b * n) % ((BigInteger)1 << 128), (Int128)a * n - (Int128)b * n); Assert.AreEqual(+(BigInteger)a, +(Int128)a); Assert.AreEqual(-(BigInteger)a, -(Int128)a); value = a; Assert.AreEqual((BigInteger)a + 1, ++value); value = a; Assert.AreEqual((BigInteger)a, value++); value = (Int128)a * b; Assert.AreEqual((BigInteger)a * b + 1, ++value); value = (Int128)a * b; Assert.AreEqual((BigInteger)a * b, value++); value = a; Assert.AreEqual((BigInteger)a - 1, --value); value = a; Assert.AreEqual((BigInteger)a, value--); value = (Int128)a * b; Assert.AreEqual((BigInteger)a * b - 1, --value); value = (Int128)a * b; Assert.AreEqual((BigInteger)a * b, value--); Assert.AreEqual((BigInteger)a * b, (Int128)a * b); Assert.AreEqual((BigInteger)a * b, a * (Int128)b); Assert.AreEqual((BigInteger)a * b, (Int128)a * (Int128)b); Assert.AreEqual((BigInteger)a * b % n, (Int128)a * b % n); Assert.AreEqual((BigInteger)a * b % n, a * (Int128)b % n); Assert.AreEqual((BigInteger)a * b % n, (Int128)a * (Int128)b % (Int128)n); Assert.AreEqual((BigInteger)a * b / n, (Int128)a * b / n); Assert.AreEqual((BigInteger)a * b / n, a * (Int128)b / n); Assert.AreEqual((BigInteger)a * b / n, (Int128)a * (Int128)b / (Int128)n); Assert.AreEqual((BigInteger)a < b, (Int128)a < b); Assert.AreEqual((BigInteger)a < b, a < (Int128)b); Assert.AreEqual((BigInteger)a < b, (Int128)a < (Int128)b); Assert.AreEqual((BigInteger)a <= b, (Int128)a <= b); Assert.AreEqual((BigInteger)a <= b, a <= (Int128)b); Assert.AreEqual((BigInteger)a <= b, (Int128)a <= (Int128)b); Assert.AreEqual((BigInteger)a > b, (Int128)a > b); Assert.AreEqual((BigInteger)a > b, a > (Int128)b); Assert.AreEqual((BigInteger)a > b, (Int128)a > (Int128)b); Assert.AreEqual((BigInteger)a >= b, (Int128)a >= b); Assert.AreEqual((BigInteger)a >= b, a >= (Int128)b); Assert.AreEqual((BigInteger)a >= b, (Int128)a >= (Int128)b); Assert.AreEqual((BigInteger)a == b, (Int128)a == b); Assert.AreEqual((BigInteger)a == b, a == (Int128)b); Assert.AreEqual((BigInteger)a == b, (Int128)a == (Int128)b); Assert.AreEqual((BigInteger)a != b, (Int128)a != b); Assert.AreEqual((BigInteger)a != b, a != (Int128)b); Assert.AreEqual((BigInteger)a != b, (Int128)a != (Int128)b); Assert.AreEqual(BigInteger.Abs(a), Int128.Abs(a)); Assert.AreEqual(BigInteger.Abs((BigInteger)a * b), Int128.Abs((Int128)a * b)); Assert.AreEqual(BigInteger.Min(a, b), Int128.Min(a, b)); Assert.AreEqual(BigInteger.Min((BigInteger)a * n, (BigInteger)b * n), Int128.Min((Int128)a * n, (Int128)b * n)); Assert.AreEqual(BigInteger.Max(a, b), Int128.Max(a, b)); Assert.AreEqual(BigInteger.Max((BigInteger)a * n, (BigInteger)b * n), Int128.Max((Int128)a * n, (Int128)b * n)); for (var j = 0; j < 2; j++) { var m = Int128.Abs(j == 0 ? (Int128)a * (Int128)b : (Int128)n * (Int128)n); var floorsqrt = Int128.FloorSqrt(m); Assert.IsTrue((BigInteger)floorsqrt * floorsqrt <= m && (BigInteger)(floorsqrt + 1) * (floorsqrt + 1) > m); var ceilingsqrt = Int128.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 ? (Int128)a * (Int128)b : (Int128)(Math.Sign(a) * Math.Sign(b) * BigInteger.Pow((BigInteger)Math.Floor(Math.Pow((double)BigInteger.Abs((BigInteger)a * b), (double)1 / 3)), 3)); var floorcbrt = Int128.FloorCbrt(m); Assert.IsTrue(Math.Sign(floorcbrt) == m.Sign && (BigInteger)Math.Abs(floorcbrt) * Math.Abs(floorcbrt) * Math.Abs(floorcbrt) <= BigInteger.Abs(m) && (BigInteger)(Math.Abs(floorcbrt) + 1) * (Math.Abs(floorcbrt) + 1) * (Math.Abs(floorcbrt) + 1) > BigInteger.Abs(m)); var ceilingcbrt = Int128.CeilingCbrt(m); Assert.IsTrue(Math.Sign(ceilingcbrt) == m.Sign && (BigInteger)(Math.Abs(ceilingcbrt) - 1) * (Math.Abs(ceilingcbrt) - 1) * (Math.Abs(ceilingcbrt) - 1) < BigInteger.Abs(m) && (BigInteger)Math.Abs(ceilingcbrt) * Math.Abs(ceilingcbrt) * Math.Abs(ceilingcbrt) >= BigInteger.Abs(m)); } } }