public static ArbitraryNumber Sub(ArbitraryNumber a, ArbitraryNumber b) { if (a.IsNegative) { if (b.IsNegative) { return(-SubstractPositives(-a, -b)); } else { return(-AddPositives(-a, b)); } } else { if (b.IsNegative) { return(AddPositives(a, -b)); } else { return(SubstractPositives(a, b)); } } }
private static ArbitraryNumber Abs(ArbitraryNumber num) { var abs = new ArbitraryNumber(num); abs.IsNegative = false; return(abs); }
private static ArbitraryNumber MultBySingleDigit(ArbitraryNumber an, int digit) { Guard.Requires(0 <= digit && digit < 10, $"Requires 0 <= {nameof(digit)} < 10, but actual value was {digit}"); var result = new ArbitraryNumber(); int carryOver = 0; foreach (int d in an.Digits.AsEnumerable().Reverse()) { int mul = d * digit + carryOver; int val = mul % 10; carryOver = (mul - val) / 10; result.Digits.Insert(0, val); } while (carryOver > 0) { int val = carryOver % 10; result.Digits.Insert(0, val); carryOver = (carryOver - val) / 10; } result.DecimalsCount = an.DecimalsCount; Trim(result); return(result); }
private static void InsertdecimalShift(ArbitraryNumber intermediateResult, int decimalShift) { for (int i = 0; i < decimalShift; i++) { intermediateResult.Digits.Insert(0, 0); } }
public static ArbitraryNumber Mult(ArbitraryNumber a, ArbitraryNumber b) { if (a.IsNegative == b.IsNegative) { return(MultPositives(Abs(a), Abs(b))); } else { return(-MultPositives(Abs(a), Abs(b))); } }
private static void AlignFractionalDigits(ArbitraryNumber num1, ArbitraryNumber num2) { if (num1.FractionalPart.Count == num2.FractionalPart.Count) { return; } ArbitraryNumber lessFractional = Selector.Min(an => an.FractionalPart.Count, num1, num2); ArbitraryNumber mostFractional = Selector.Max(an => an.FractionalPart.Count, num1, num2); lessFractional.Digits.AddRange(Enumerable.Repeat(0, mostFractional.FractionalPart.Count - lessFractional.FractionalPart.Count)); lessFractional.DecimalsCount += mostFractional.FractionalPart.Count - lessFractional.FractionalPart.Count; }
private static void Trim(ArbitraryNumber num) { if (num.DecimalsCount > 0) { int initialDigitsCount = num.Digits.Count; num.Digits.TrimRight(0, num.DecimalsCount); num.DecimalsCount -= initialDigitsCount - num.Digits.Count; } num.Digits.TrimLeft(0); if (!num.Digits.Any()) { num.DecimalsCount = 0; } }
private static ArbitraryNumber SubstractPositives(ArbitraryNumber a, ArbitraryNumber b) { var num1 = new ArbitraryNumber(a); var num2 = new ArbitraryNumber(b); AlignFractionalDigits(num1, num2); var result = new ArbitraryNumber(); var enumerator = new ParallelEnumerator <int>(num1.Digits.AsEnumerable().Reverse(), num2.Digits.AsEnumerable().Reverse()); int carryOver = 0; while (enumerator.Next()) { int val1 = enumerator.Current[0]; int val2 = enumerator.Current[1]; int sub = val1 - val2 - carryOver; int val = 0; if (sub < 0) { val = 10 + sub; carryOver = 1; } else { val = sub; carryOver = 0; } result.Digits.Insert(0, val); } if (carryOver > 0) { result.Digits.Insert(0, carryOver); result.IsNegative = true; } result.DecimalsCount = num1.DecimalsCount; Trim(result); return(result); }
private static ArbitraryNumber MultPositives(ArbitraryNumber arbitraryNumber1, ArbitraryNumber arbitraryNumber2) { var result = new ArbitraryNumber(); var an = new ArbitraryNumber(arbitraryNumber1); foreach (int digit in arbitraryNumber2.Digits.AsEnumerable().Reverse()) { result += MultBySingleDigit(an, digit); an.Digits.Add(0); } result.DecimalsCount += arbitraryNumber2.DecimalsCount; Trim(result); return(result); }
public static ArbitraryNumber Pow(this ArbitraryNumber a, int pow) { if (pow == 0) { return(1); } ArbitraryNumber result = 1; for (int i = 0; i < pow; i++) { result *= a; } Trim(result); return(pow > 0 ? result : 1 / result); }
public static ArbitraryNumber Min(ArbitraryNumber a, ArbitraryNumber b) { if (a.IntegerPart.Count < b.IntegerPart.Count) { return(a); } if (a.IntegerPart.Count > b.IntegerPart.Count) { return(b); } if (a.Digits[0] <= b.Digits[0]) { return(a); } else { return(b); } }
private static ArbitraryNumber AddPositives(ArbitraryNumber a, ArbitraryNumber b) { var num1 = new ArbitraryNumber(a); var num2 = new ArbitraryNumber(b); AlignFractionalDigits(num1, num2); var result = new ArbitraryNumber(); var enumerator = new ParallelEnumerator <int>(num1.Digits.AsEnumerable().Reverse(), num2.Digits.AsEnumerable().Reverse()); int carryOver = 0; while (enumerator.Next()) { int val1 = enumerator.Current[0]; int val2 = enumerator.Current[1]; int added = val1 + val2 + carryOver; int val = added % 10; carryOver = (added - val) / 10; result.Digits.Insert(0, val); } if (carryOver > 0) { result.Digits.Insert(0, carryOver); } result.DecimalsCount = num1.DecimalsCount; Trim(result); return(result); }
public static ArbitraryNumber Pow(ArbitraryNumber a, ArbitraryNumber pow) { throw new System.NotImplementedException(); }
public ArbitraryNumber(ArbitraryNumber other) : this(new List <int>(other?.Digits ?? new List <int>()), other?.DecimalsCount ?? 0) { }