public void SafeMod() { var preds = new List <long>(); for (int i = 0; i <= 100; i++) { preds.Add(i); preds.Add(-i); preds.Add(i); preds.Add(long.MinValue + i); preds.Add(long.MaxValue - i); } foreach (var a in preds) { foreach (var b in preds) { if (b <= 0) { continue; } var ans = (long)((new BigInteger(a) % b + b) % b); InternalMath.SafeMod(a, b).Should().Be(ans); } } }
public void InvGcdBound() { var pred = new List <long>(); for (int i = 0; i <= 10; i++) { pred.Add(i); pred.Add(-i); pred.Add(long.MinValue + i); pred.Add(long.MaxValue - i); pred.Add(long.MinValue / 2 + i); pred.Add(long.MinValue / 2 - i); pred.Add(long.MaxValue / 2 + i); pred.Add(long.MaxValue / 2 - i); pred.Add(long.MinValue / 3 + i); pred.Add(long.MinValue / 3 - i); pred.Add(long.MaxValue / 3 + i); pred.Add(long.MaxValue / 3 - i); } pred.Add(998244353); pred.Add(1_000_000_007); pred.Add(1_000_000_009); pred.Add(-998244353); pred.Add(-1_000_000_007); pred.Add(-1_000_000_009); foreach (var a in pred) { foreach (var b in pred) { if (b <= 0) { continue; } long a2 = InternalMath.SafeMod(a, b); (long first, long second) = InternalMath.InvGCD(a, b); var g = Gcd(a2, b); first.Should().Be(g); second.Should().BeGreaterOrEqualTo(0); (b / first).Should().BeGreaterOrEqualTo(second); ((long)(new BigInteger(second) * a2 % b)).Should().Be(g % b); } } }