/// <summary> /// Calculates a quotient and remainder of division of a two ALong instances. /// </summary> /// <param name="num1">Divident</param> /// <param name="num2">Divisor</param> /// <returns>A Tuple of Quotient and Remainder.</returns> public static Tuple<ALong, ALong> Divide(ALong num1, ALong num2) { var num2a = Abs(num2); if (num2a < Int32.MaxValue) { return DivInt(num1, num2.ToString().ToInt()); } if (num2 == 0) { throw new ArgumentException("Division by zero"); } if (num1 == 0) { return new Tuple<ALong, ALong>(new ALong(0), new ALong(0)); } var num1a = Abs(num1); if (num1a == num2a) { return new Tuple<ALong, ALong>(new ALong(1).SetNegative(num1.IsNegative != num2.IsNegative), new ALong(0)); } if (num1a < num2a) { return new Tuple<ALong, ALong>(new ALong(0), new ALong(num1)); } var b = 10; // base var down = new ALong(0); // Get upper limit var up = new ALong(b); while (num1a > num2a * up) { up = up * b; } // Divide while (up - down > 1) { var cur = (down + up) / 2; var c = num2a * (cur); if (c < num1a) { down = cur; continue; } if (c > num1a) { up = cur; continue; } if (c == num1a) { down = cur; up = cur; continue; } } var remainder = num1a - down * num2a; down.SetNegative(num1.IsNegative != num2.IsNegative); remainder.SetNegative(num1.IsNegative); return new Tuple<ALong, ALong>(down, remainder); }
/// <summary> /// Calculates a quotient and remainder of division of an ALong instance and integer. /// </summary> /// <param name="num1">Divident</param> /// <param name="num2">Divisor</param> /// <returns>A Tuple of Quotient and Remainder.</returns> public static Tuple<ALong, ALong> DivInt(ALong num1, int num2) { if (num2 == 0) { throw new ArgumentException("Division by zero"); } if (num1 == 0) { return new Tuple<ALong, ALong>(new ALong(0), new ALong(0)); } if (num1 == num2) { return new Tuple<ALong, ALong>(new ALong(1), new ALong(0)); } if (Abs(num1) < Math.Abs(num2)) { return new Tuple<ALong, ALong>(new ALong(0), new ALong(num1)); } var strres = ""; string divident = ""; var dividentInt = 0L; var divisor = Math.Abs(num2); int remainder = 0; for (int i = 0; i < num1.Length(); i++) { divident += num1.Num[i]; dividentInt = divident.ToLong(); if (dividentInt < divisor) { if (strres != "") { strres += "0"; } continue; } var res = dividentInt / divisor; strres += res; divident = (dividentInt - res * divisor).ToString(); } remainder = divident.ToInt(); return new Tuple<ALong, ALong>(new ALong(strres).SetNegative(num1.IsNegative != num2 < 0), new ALong(num1.IsNegative ? remainder * -1 : remainder)); }
public void ALongSumTest() { Assert.AreEqual("1248", (new ALong("00001239") + new ALong("000009")).ToString()); Assert.AreEqual("10", (new ALong("1") + new ALong("9")).ToString()); Assert.AreEqual("180", (new ALong("90") + new ALong("90")).ToString()); Assert.AreEqual("100000000000000000000000000000000000000000000005", (new ALong("100000000000000000000000000000000000000000000000") + new ALong("5")).ToString()); var a = new ALong("10"); // Add string (aware of number pasing errors) a += "20"; Assert.AreEqual("30", a.ToString()); // Add int a += 10; Assert.AreEqual("40", a.ToString()); // Add long a += 10L; Assert.AreEqual("50", a.ToString()); Assert.AreEqual("10000", (new ALong("1") + new ALong("9999")).ToString()); Assert.AreEqual("-1", (new ALong("0") + new ALong("-1")).ToString()); Assert.AreEqual("-999", (new ALong("1") + new ALong("-1000")).ToString()); a += -60; Assert.AreEqual("-10", a.ToString()); }
public void ALongSubTest() { Assert.AreEqual("9886", AMath.Sub(new ALong(10509), new ALong(623)).ToString()); Assert.AreEqual("999", AMath.Sub(new ALong(1000), new ALong(1)).ToString()); Assert.AreEqual("1000", AMath.Sub(new ALong(999), new ALong(-1)).ToString()); Assert.AreEqual("-1000", AMath.Sub(new ALong(-1), new ALong(999)).ToString()); Assert.AreEqual("998", AMath.Sub(new ALong(-1), new ALong(-999)).ToString()); Assert.AreEqual("2", AMath.Sub(new ALong("1"), new ALong(-1)).ToString()); Assert.AreEqual("-1", AMath.Sub(new ALong("99"), new ALong(100)).ToString()); var a = new ALong(10); a -= 2; Assert.AreEqual("8", a.ToString()); a -= 8; Assert.AreEqual("0", a.ToString()); a += 10; a -= 15; Assert.AreEqual("-5", a.ToString()); a -= "100000000000000000000000000000000000000000000005"; Assert.AreEqual("-100000000000000000000000000000000000000000000010", a.ToString()); a += "11"; Assert.AreEqual("-99999999999999999999999999999999999999999999999", a.ToString()); Assert.IsTrue(a == "-99999999999999999999999999999999999999999999999"); Assert.IsFalse(a > "-99999999999999999999999999999999999999999999999"); Assert.IsTrue(a >= "-99999999999999999999999999999999999999999999999"); }
public void MulTest() { // basics Assert.IsTrue(new ALong() * new ALong() == 0); Assert.IsTrue(new ALong() * new ALong() == "0"); Assert.IsTrue(new ALong(123) * new ALong() == "0"); Assert.IsTrue(new ALong(-123) * new ALong() == "0"); Assert.IsTrue(new ALong() * new ALong(123) == "0"); Assert.IsTrue(new ALong() * new ALong(-123) == "0"); Assert.IsTrue(new ALong(1) * new ALong(1) == "1"); Assert.IsTrue(new ALong(1) * new ALong(-1) == "-1"); Assert.IsTrue(new ALong(-1) * new ALong(-1) == "1"); Assert.IsTrue(new ALong(-1) * new ALong(1) == "-1"); Assert.IsTrue(new ALong(123) * new ALong(999) == "122877"); Assert.IsTrue(new ALong(-123) * new ALong(999) == "-122877"); Assert.IsTrue(new ALong(123) * new ALong(-999) == "-122877"); Assert.IsTrue(new ALong(-123) * new ALong(-999) == "122877"); var a = BigInteger.Parse("1010101010101010101010101010101010101010101010101010"); var b = BigInteger.Parse("202020202020202020202020202020202020202020202020202020202020"); var c = a * b; // 204060810121416182022242628303234363840424446485052525252525048464442403836343230282624222018161412100806040200 Assert.IsTrue(new ALong("1010101010101010101010101010101010101010101010101010") * new ALong("202020202020202020202020202020202020202020202020202020202020") == "204060810121416182022242628303234363840424446485052525252525048464442403836343230282624222018161412100806040200"); Assert.IsTrue(new ALong("1010101010101010101010101010101010101010101010101010") * new ALong("202020202020202020202020202020202020202020202020202020202020") == c.ToString()); var aa = new ALong("1010101010101010101010101010101010101010101010101010"); var bb = new ALong("202020202020202020202020202020202020202020202020202020202020"); var cc = aa * bb; Assert.IsTrue(cc == "204060810121416182022242628303234363840424446485052525252525048464442403836343230282624222018161412100806040200"); }
public void BetweenTest() { AssertFails(10L, ALong.Between(10L, 13L)); AssertPasses(11L, ALong.Between(10L, 13L)); AssertPasses(12L, ALong.Between(10L, 13L)); AssertFails(13L, ALong.Between(10L, 13L)); }
public void MulTenTest() { var a = new ALong(10); a.MulBase(5); a += 10; Assert.IsTrue(a == "1000010"); }
public void BetweenIncludingTest() { AssertFails(9L, ALong.BetweenIncluding(10L, 13L)); AssertPasses(10L, ALong.BetweenIncluding(10L, 13L)); AssertPasses(11L, ALong.BetweenIncluding(10L, 13L)); AssertPasses(12L, ALong.BetweenIncluding(10L, 13L)); AssertPasses(13L, ALong.BetweenIncluding(10L, 13L)); AssertFails(14L, ALong.BetweenIncluding(10L, 13L)); }
public void EqualToTest() { AssertPasses(null, ALong.EqualTo(null)); AssertFails(0, ALong.EqualTo(null)); AssertFails(null, ALong.EqualTo(0)); AssertFails(4L, ALong.EqualTo(5L)); AssertPasses(5L, ALong.EqualTo(5L)); AssertFails(6L, ALong.EqualTo(5L)); }
public void BigPowTest() { var a = BigInteger.Parse("132121923409128340918230491802394810"); var aa = BigInteger.Pow(a, 50); var b = new ALong("132121923409128340918230491802394810"); var bb = AMath.Pow(b, 50); Assert.IsTrue(bb == aa.ToString()); }
public void AssertDivInt(string num1, int num2) { var a = new ALong(num1); var b = AMath.DivInt(a, num2); //var b = ALong.Divide(a, new ALong(num2)); var aa = BigInteger.Parse(num1); var bb = new Tuple <BigInteger, BigInteger>(aa / num2, aa % num2); Assert.IsTrue(b.Item1 == bb.Item1.ToString()); Assert.IsTrue(b.Item2 == bb.Item2.ToString()); }
public void AssertDivide(string num1, string num2) { var a = new ALong(num1); var b = new ALong(num2); var d = AMath.Divide(a, b); var aa = BigInteger.Parse(num1); var bb = BigInteger.Parse(num2); var dd = aa / bb; var rr = aa % bb; Assert.IsTrue(d.Item1 == dd.ToString()); Assert.IsTrue(d.Item2 == rr.ToString()); }
public void Examples() { var a = new ALong(10); // Initialize with 10 var b = new ALong("10"); // Initialize with 10 // Sum a += 20; // 30 a += 20L; // 50 a += "20"; // 70 a += new ALong("20"); // 90 a -= b; // 80 a += b; // 90 a -= -10; // 100 // Comparing var cmp = a < b; // false cmp = a <= b; // false cmp = a > b; // true cmp = a > 200; // false cmp = a >= "100"; // true // Multiplication a *= 10; // 1000 a *= b; // 10000 a = a * b; // 100000 a = a * "-10"; // -1000000 // Division a /= -1000; // 1000 a /= b; // 100 // Remainder var c = a % (b + 3); // 9 c = a % 13; // 9 c = b % 5; // 0 c = b % 3; // 1 // Power c = AMath.Pow(a, b); // 100^10 = 100000000000000000000 // Base Conversion string d; d = "c367b3eb9df3bd5bdca9a3516af2d4da".FromArbitraryBase(16).ToArbitraryBase(62); // "5WITyx9Hj07ZJvDzZcZHrI" d = d.FromArbitraryBase(62).ToArbitraryBase(16); // "c367b3eb9df3bd5bdca9a3516af2d4da" }
public void ALongMaxMinTest() { var a = new ALong("1"); var b = new ALong("2"); var c = new ALong("-5"); var d = new ALong("-3"); Assert.AreEqual(b, AMath.Max(a, b)); Assert.AreEqual(b, AMath.Max(c, b)); Assert.AreEqual(a, AMath.Min(a, b)); Assert.AreEqual(c, AMath.Min(c, a)); Assert.AreEqual(c, AMath.Min(c, b)); Assert.AreEqual(c, AMath.Min(c, d)); Assert.AreEqual(d, AMath.Max(c, d)); }
/// <summary> /// Returns the smaller of two ALong instances. /// </summary> /// <param name="num1">The first of two ALong instances to compare.</param> /// <param name="num2">The second of two ALong instances to compare.</param> /// <returns>Parameter num1 or num2, whichever is smaller.</returns> public static ALong Min(ALong num1, ALong num2) { if (num1 > num2) { return num2; } return num1; }
/// <summary> /// Calculates a product of a two ALong instances, a.k.a "School" method (very slow) /// </summary> /// <param name="num1">Multiplicand</param> /// <param name="num2">Multiplier</param> /// <returns>Product of num1 and num2.</returns> //TODO: replace with Karatsuba, Schönhage–Strassen or Knuth. (Fast Fourier transform?). //TODO: use base of size of Int32 to "shorten" sizes of numbers within multiplication speed being kept. public static ALong Mul(ALong num1, ALong num2) { var result = new ALong(0); if (num1 == 0 || num2 == 0) { return result; } var carry = 0; for (int i = 0; i < num1.Length(); i++) { var n1 = num1.GetRNumAtIndex(i); var res = String.Empty; var n2len = num2.Length(); carry = 0; for (int k = 0; k < n2len; k++) { var n2 = num2.GetRNumAtIndex(k); var ns = n1 * n2 + carry; carry = ns / 10; res = (ns % 10) + res; if (k == n2len - 1 && carry > 0) { res = carry.ToString() + res; } } var mulres = new ALong(res); mulres.MulBase(i); result += mulres; } if (num1.IsNegative != num2.IsNegative) { result.SetNegative(true); } return result; }
/// <summary> /// Calculates a specified ALong number raised to the specified power. /// </summary> /// <param name="num">ALong instance to be raised to a power.</param> /// <param name="exp">ALong instance that specifies a power.</param> /// <returns>New ALong instance indicating specified ALong number raised to the specified power.</returns> public static ALong Pow(ALong num, ALong exp) { var res = new ALong(1); while (exp != 0) { if (exp % 2 != 0) { res *= num; exp -= 1; } num *= num; exp /= 2; } return res; }
/// <summary> /// Calculates a specified ALong number raised to the specified power. /// </summary> /// <param name="num">ALong instance to be raised to a power.</param> /// <param name="exp">string representation of a number that specifies a power.</param> /// <returns>New ALong instance indicating specified ALong number raised to the specified power.</returns> public static ALong Pow(ALong num, string exp) { return Pow(num, new ALong(exp)); }
public ATestDto MyPrimLongProp(long expect) { MyPrimLongProp(ALong.EqualTo(expect)); return(this); }
public void LessThanOrEqualToTest() { AssertPasses(9L, ALong.LessThanOrEqualTo(10L)); AssertPasses(10L, ALong.LessThanOrEqualTo(10L)); AssertFails(11L, ALong.LessThanOrEqualTo(10L)); }
public void NotTest() { AssertPasses(9L, ALong.Not(10L)); AssertFails(10L, ALong.Not(10L)); AssertPasses(11L, ALong.Not(10L)); }
/// <summary> /// Calculates a specified ALong number raised to the specified power. /// </summary> /// <param name="num">ALong instance to be raised to a power.</param> /// <param name="exp">int value that specifies a power.</param> /// <returns>New ALong instance indicating specified ALong number raised to the specified power.</returns> public static ALong Pow(ALong num, int exp) { return Pow(num, new ALong(exp)); }
/// <summary> /// Calculates a Subtraction of a two ALong values. /// </summary> /// <param name="num1">Minuend</param> /// <param name="num2">Subtrahend</param> /// <returns>ALong instance representing a difference between minuend and subtrahend.</returns> public static ALong Sub(ALong num1, ALong num2) { if (num1 == num2) { return new ALong(0); } if (!num1.IsNegative && !num2.IsNegative) { return Sum(num1, new ALong(num2).SetNegative(true)); } if (!num1.IsNegative && num2.IsNegative) { return Sum(num1, new ALong(num2).SetNegative(false)); } if (num1.IsNegative && !num2.IsNegative) { return Sum(new ALong(num1).SetNegative(false), new ALong(num2).SetNegative(false)).SetNegative(true); } if (num1.IsNegative && num2.IsNegative) { return Sum(num1, new ALong(num2).SetNegative(false)); } return new ALong(0); }
/// <summary> /// Returns the larger of two ALong instances. /// </summary> /// <param name="num1">The first of two ALong instances to compare.</param> /// <param name="num2">The second of two ALong instances to compare.</param> /// <returns>Parameter num1 or num2, whichever is larger.</returns> public static ALong Max(ALong num1, ALong num2) { if (num1 < num2) { return num2; } return num1; }
public ATestDto MyNullLongProp(long?expect) { MyNullLongProp(ALong.EqualTo(expect)); return(this); }
public void NotNullTest() { AssertPasses(10L, ALong.NotNull()); AssertFails(null, ALong.NotNull()); }
public ATestDto MyNullLongPropNull() { MyNullLongProp(ALong.Null()); return(this); }
/// <summary> /// Calculates a Summary of a two ALong values. /// </summary> /// <param name="num1">First addend</param> /// <param name="num2">Second addend</param> /// <returns>ALong instance representing a sum of two addends.</returns> public static ALong Sum(ALong num1, ALong num2) { if (num1.IsNegative == num2.IsNegative) { return AbsSum(num1, num2).SetNegative(num1.IsNegative); } var n1 = Abs(num1); var n2 = Abs(num2); var result = AbsSub(n1, n2); if (n1 < n2) { result.SetNegative(num2.IsNegative); } if (n1 > n2) { result.SetNegative(num1.IsNegative); } return result; }
/// <summary> /// Creates a new ALong instance with the absolute value. /// </summary> /// <param name="num">ALong instance.</param> /// <returns>New ALong instance with an absolute value.</returns> public static ALong Abs(ALong num) { return new ALong(num.Num); }
/// <summary> /// Calculates a Subtraction of a two ALong absolute values, a.k.a "School" method. /// </summary> /// <param name="num1">Minuend</param> /// <param name="num2">Subtrahend</param> /// <returns>ALong instance representing a difference between absolute values of minuend and subtrahend.</returns> private static ALong AbsSub(ALong num1, ALong num2) { if (num1 == num2) { return new ALong(0); } var big = AMath.Max(Abs(num1), Abs(num2)); var small = AMath.Min(Abs(num1), Abs(num2)); var result = String.Empty; int carry = 0; for (int i = 0; i < big.Length(); i++) { var n1 = big.GetRNumAtIndex(i); var n2 = small.GetRNumAtIndex(i); var ns = n1 - carry; carry = 0; if (ns < n2) { ns += 10; carry = 1; } ns = ns - n2; result = ns.ToString() + result; } return new ALong(result); }
public void AssertDivInt(string num1, int num2) { var a = new ALong(num1); var b = AMath.DivInt(a, num2); //var b = ALong.Divide(a, new ALong(num2)); var aa = BigInteger.Parse(num1); var bb = new Tuple<BigInteger, BigInteger>(aa / num2, aa % num2); Assert.IsTrue(b.Item1 == bb.Item1.ToString()); Assert.IsTrue(b.Item2 == bb.Item2.ToString()); }
/// <summary> /// Calculates a Summary of a two ALong absolute values, a.k.a "School" method. /// </summary> /// <param name="num1">First addend</param> /// <param name="num2">Second addend</param> /// <returns>ALong instance representing a sum of two addends.</returns> private static ALong AbsSum(ALong num1, ALong num2) { var result = String.Empty; int carry = 0; var max = Math.Max(num1.Length(), num2.Length()); for (int i = 0; i < max; i++) { var n1 = num1.GetRNumAtIndex(i); var n2 = num2.GetRNumAtIndex(i); var ns = n1 + n2 + carry; carry = 0; if (ns >= 10) { ns = ns - 10; carry = 1; } result = ns.ToString() + result; if (i == max - 1 && carry > 0) { result = carry.ToString() + result; } } return new ALong(result); }
public void GreaterOrEqualToTest() { AssertFails(0L, ALong.GreaterOrEqualTo(1L)); AssertPasses(1L, ALong.GreaterOrEqualTo(1L)); AssertPasses(2L, ALong.GreaterOrEqualTo(1L)); }
public void LessThanTest() { AssertPasses(9L, ALong.LessThan(10L)); AssertFails(10L, ALong.LessThan(10L)); AssertFails(11L, ALong.LessThan(10L)); }
public void GreaterThanTest() { AssertFails(9L, ALong.GreaterThan(10L)); AssertFails(10L, ALong.GreaterThan(10L)); AssertPasses(11L, ALong.GreaterThan(10L)); }