public void TestCompareTo() { var r = new RandomGenerator(); for (var i = 0; i < 500; ++i) { ERational bigintA = RandomObjects.RandomERational(r); ERational bigintB = RandomObjects.RandomERational(r); ERational bigintC = RandomObjects.RandomERational(r); TestCommon.CompareTestRelations(bigintA, bigintB, bigintC); } TestCommon.CompareTestLess(ERational.Zero, ERational.NaN); ERational rat, rat2; for (var i = 0; i < 100; ++i) { EInteger num = RandomObjects.RandomEInteger(r); if (num.IsZero) { // Skip if number is 0; 0/1 and 0/2 are // equal in that case continue; } num = num.Abs(); rat = ERational.Create(num, EInteger.One); rat2 = ERational.Create(num, (EInteger)2); TestCommon.CompareTestLess(rat2, rat); TestCommon.CompareTestGreater(rat, rat2); } TestCommon.CompareTestLess( ERational.Create(EInteger.One, (EInteger)2), ERational.Create((EInteger)4, EInteger.One)); for (var i = 0; i < 100; ++i) { EInteger num = RandomObjects.RandomEInteger(r); EInteger den = RandomObjects.RandomEInteger(r); if (den.IsZero) { den = EInteger.One; } rat = ERational.Create(num, den); for (int j = 0; j < 10; ++j) { EInteger num2 = num; EInteger den2 = den; EInteger mult = RandomObjects.RandomEInteger(r); if (mult.IsZero || mult.Equals(EInteger.One)) { mult = (EInteger)2; } num2 *= (EInteger)mult; den2 *= (EInteger)mult; rat2 = ERational.Create(num2, den2); TestCommon.CompareTestEqual(rat, rat2); } } }
/// <summary> /// Finds greatest common divisor (with Euler's algorithm) /// </summary> /// <param name="a"> /// First number /// </param> /// <param name="b"> /// Second number /// </param> /// <returns> /// Returns such c that all are true /// a | c /// b | c /// !∃ d > c, /// a | d /// b | d /// </returns> private static EInteger _GCD(EInteger a, EInteger b) { a = a.Abs(); b = b.Abs(); while (a * b > 0) { if (a > b) { a %= b; } else { b %= a; } } return(a == EInteger.Zero ? b : a); }
/// <summary> /// <a href="https://en.wikipedia.org/wiki/Least_common_multiple#Using_the_greatest_common_divisor"/> /// </summary> public static EInteger Lcm(this EInteger bigintFirst, EInteger bigintSecond) => bigintFirst.IsZero && bigintSecond.IsZero ? EInteger.Zero : bigintFirst.Abs().Divide(bigintFirst.Gcd(bigintSecond)).Multiply(bigintSecond.Abs());