// Berechne die quadratwurzel aus q (Heronverfahren) // // 1 / q \ // xn+1 = --- * | xn + ---- | // 2 \ xn / // Each iteration about doubles the correct decimal places! public static VeryLong Sqrt(VeryLong input, int numberOfDigits) { int additionalCalcDigits = 5; int additionalLimitDigits = 0; VeryLong limit = new VeryLong("0." + VeryLong.GetZeros(numberOfDigits + additionalLimitDigits) + "1" + VeryLong.GetZeros(additionalCalcDigits - additionalLimitDigits - 1)); VeryLong xnew; VeryLong delta; VeryLong xn = new VeryLong(input.ToString()); int i = 0; while (true) { VeryLong summand2 = input.DivideBy(xn, numberOfDigits + additionalCalcDigits); VeryLong factor = xn.Add(summand2); xnew = new VeryLong("0.5").Multiply(factor); delta = xnew.Subtract(xn); Console.WriteLine("i " + i); Console.WriteLine("Sqrt delta: " + delta.ToString()); Console.WriteLine("limit: " + limit.ToString()); Console.WriteLine("Sqrt: " + xnew.ToString()); xn = xnew; i++; if (!delta.Abs().IsLargerOrEqual(limit)) { break; } } xn.LimitPrecisionTo(numberOfDigits); return(xn); }
public VeryLong DivideBy(VeryLong divisor, out VeryLong remainder) { string dividendString = ""; string divisorString = divisor.ToString(); string quotientDigit = ""; string quotient = ""; string mult = ""; string diff = ""; for (int i = 0; i < Length(); i++) { dividendString += GetFirstDigit(i); dividendString = VeryLong.RemoveLeadingZeros(dividendString); quotientDigit = DivideSimple(dividendString, divisorString); quotient += quotientDigit; mult = (new VeryLong(quotientDigit).Multiply(new VeryLong(divisorString))).ToString(); diff = (new VeryLong(dividendString).Subtract(new VeryLong(mult))).ToString(); dividendString = diff; } VeryLong quotientResult = new VeryLong(quotient); remainder = new VeryLong(diff); quotientResult.RemoveLeadingZeros(); return(quotientResult); }
// 4 4 4 // pi = 3 + ------- - ------- + ------- +- ... // 2*3*4 4*5*6 6*7*8 public static VeryLong GetPiTermEuler(int n, int numberOfDigits) { VeryLong four = new VeryLong("4"); VeryLong quotient = four.DivideBy(GetPiTermDivisorEuler(n), numberOfDigits); return(quotient); }
public static VeryLong AddSummands(List <string> summands) { VeryLong sum = new VeryLong(summands[0]); for (int i = 1; i < summands.Count; i++) { sum = sum.Add(new VeryLong(summands[i])); } return(sum); }
public static VeryLong GetStartValueBBP(int numberOfDigits) { // n = 0 --> term = 4/1 - 2/4 - 1/5 - 1/6 VeryLong subtrahend1 = new VeryLong("0.5"); VeryLong subtrahend2 = new VeryLong("0.2"); VeryLong subtrahend3 = new VeryLong(1.ToString()).DivideBy(new VeryLong(6.ToString()), numberOfDigits); VeryLong start = new VeryLong(4.ToString()).Subtract(subtrahend1).Subtract(subtrahend2).Subtract(subtrahend3); return(start); }
public static VeryLong GetPiTermDivisorEuler(int n) { // 1 --> 2*3*4 // 2 --> 4*5*6 // 3 --> 6*7*8 VeryLong factor1 = new VeryLong("2").Multiply(new VeryLong(n.ToString())); VeryLong factor2 = new VeryLong(factor1.Add(new VeryLong("1")).ToString()); VeryLong factor3 = new VeryLong(factor2.Add(new VeryLong("1")).ToString()); return(factor1.Multiply(factor2).Multiply(factor3)); }
public VeryLong Subtract(VeryLong subtrahend) { int minuendDecimalPlaces = GetDecimalPlaces(); int subtrahendDecimalPlaces = subtrahend.GetDecimalPlaces(); int decimalPlaces = Math.Max(minuendDecimalPlaces, subtrahendDecimalPlaces); FillUpDecimalPlacesWithZero(decimalPlaces); subtrahend.FillUpDecimalPlacesWithZero(decimalPlaces); string result = ""; int diff = 0; int borrow = 0; int currentLastDigit = 0; int currentLastDigitSubtrahend = 0; int i = 0; if (!IsLargerOrEqual(subtrahend)) { // swap: minuend is smaller than subtrahend --> result is negative VeryLong newMinuend = subtrahend; VeryLong newSubtrahend = new VeryLong(ToString()); VeryLong difference = newMinuend.Subtract(newSubtrahend); return(new VeryLong("-" + difference.ToString())); } while (Length() > i || subtrahend.Length() > i || borrow != 0) { if (GetLastDigit(i) == ".") { result = result.Insert(0, "."); i++; continue; } currentLastDigit = int.Parse(GetLastDigit(i)); currentLastDigitSubtrahend = int.Parse(subtrahend.GetLastDigit(i)); diff = currentLastDigit - currentLastDigitSubtrahend - borrow; if (diff < 0) { borrow = 1; diff += 10; } else { borrow = 0; } result = result.Insert(0, diff.ToString()); i++; } result = RemoveLeadingZeros(result); return(new VeryLong(result)); }
/// <summary> /// The result of DivideSimple ist 0, 1, 2, ..., 9 /// </summary> public static string DivideSimple(string dividendString, string divisorString) { for (int tryQuotient = 9; tryQuotient > 0; tryQuotient--) { VeryLong mult = new VeryLong(divisorString).Multiply(new VeryLong(tryQuotient.ToString())); if (new VeryLong(dividendString).IsLargerOrEqual(mult)) { return(tryQuotient.ToString()); } } return("0"); }
public VeryLong Multiply(VeryLong other) { int numberDecimalPlaces = GetDecimalPlaces(); int numberDecimalPlacesOther = other.GetDecimalPlaces(); int resultDecialPlaces = numberDecimalPlaces + numberDecimalPlacesOther; other = RemoveDecimalPlaces(other); string integerStringCopy = _integerString; _integerString = _integerString.Replace(".", ""); List <string> multiplicationResults = new List <string>(); string multiplicationResult = GetZeros(1); int currentLastDigit = 0; int currentLastDigitOther = 0; int resultDigit = 0; int behalte = 0; int mult = 0; int indexOther = 0; int index = 0; while (Length() > index) { indexOther = 0; behalte = 0; multiplicationResult = GetZeros(index); while (other.Length() > indexOther || behalte != 0) { currentLastDigit = int.Parse(GetLastDigit(index)); currentLastDigitOther = int.Parse(other.GetLastDigit(indexOther)); mult = currentLastDigit * currentLastDigitOther + behalte; behalte = mult / 10; resultDigit = mult % 10; multiplicationResult = multiplicationResult.Insert(0, resultDigit.ToString()); indexOther++; } index++; multiplicationResults.Add(multiplicationResult); } VeryLong mainResult = VeryLong.AddSummands(multiplicationResults); mainResult.SetDecimalPlaces(resultDecialPlaces); mainResult.RemoveLeadingZeros(); _integerString = integerStringCopy; return(mainResult); }
public VeryLong DivideBy(VeryLong divisor, int numberOfDigits) { int numberDecimalPlacesDivisor = divisor.GetDecimalPlaces(); divisor = RemoveDecimalPlaces(divisor); FillUpDecimalPlacesWithZero(numberOfDigits + numberDecimalPlacesDivisor); string dividendString = ""; string divisorString = divisor.ToString(); string quotientDigit = ""; string quotient = ""; string mult = ""; string diff = ""; for (int i = 0; i < Length(); i++) { if (GetFirstDigit(i) == ".") { quotient += "."; continue; } dividendString += GetFirstDigit(i); dividendString = VeryLong.RemoveLeadingZeros(dividendString); quotientDigit = DivideSimple(dividendString, divisorString); quotient += quotientDigit; mult = (new VeryLong(quotientDigit).Multiply(new VeryLong(divisorString))).ToString(); diff = (new VeryLong(dividendString).Subtract(new VeryLong(mult))).ToString(); dividendString = diff; } VeryLong quotientResult = new VeryLong(quotient); int resultDecimalPlaces = quotientResult.GetDecimalPlaces(); quotientResult = RemoveDecimalPlaces(quotientResult); quotientResult.SetDecimalPlaces(resultDecimalPlaces - numberDecimalPlacesDivisor); quotientResult.RemoveLeadingZeros(); quotientResult.LimitPrecisionTo(numberOfDigits); return(quotientResult); }
public bool IsLargerOrEqual(VeryLong other) { string firstInteger = GetInteger(); string otherInteger = other.GetInteger(); // compare integers (number in front of decimal point) if (firstInteger.Length > otherInteger.Length) { return(true); } else if (firstInteger.Length < otherInteger.Length) { return(false); } else { int isLargerOrEqual = firstInteger.CompareTo(otherInteger.ToString()); if (isLargerOrEqual == -1) // other is smaller { return(false); } else if (isLargerOrEqual == 1) // other is larger { return(true); } else // integers are equal --> compare decimal digits { string decimalDigits = GetDecimalDigits(); string otherDecimalDigits = other.GetDecimalDigits(); isLargerOrEqual = decimalDigits.CompareTo(otherDecimalDigits); if (isLargerOrEqual == -1) // other is smaller { return(false); } else { return(true); } } } }
public VeryLong Add(VeryLong other) { int summand1DecimalPlaces = GetDecimalPlaces(); int summand2DecimalPlaces = other.GetDecimalPlaces(); int decimalPlaces = Math.Max(summand1DecimalPlaces, summand2DecimalPlaces); FillUpDecimalPlacesWithZero(decimalPlaces); other.FillUpDecimalPlacesWithZero(decimalPlaces); string result = ""; int sum = 0; int behalte = 0; int resultDigit = 0; int currentLastDigit = 0; int currentLastDigitOther = 0; int i = 0; while (Length() > i || other.Length() > i || behalte != 0) { if (GetLastDigit(i) == ".") { result = result.Insert(0, "."); i++; continue; } currentLastDigit = int.Parse(GetLastDigit(i)); currentLastDigitOther = int.Parse(other.GetLastDigit(i)); sum = currentLastDigit + currentLastDigitOther + behalte; behalte = sum / 10; resultDigit = sum % 10; result = result.Insert(0, resultDigit.ToString()); i++; } return(new VeryLong(result)); }
// 1 / 4 2 1 1 \ //------ * |----- - ------ - ------ - ------ | // 16^n \ 8n+1 8n+4 8n+5 8n+6 / public static VeryLong GetPiTermBBP(int n, int numberOfDigits, ref VeryLong factor) { VeryLong factor16 = new VeryLong(16.ToString()); factor = factor.DivideBy(factor16, numberOfDigits); VeryLong summand1 = new VeryLong(4.ToString()); VeryLong divisor1 = new VeryLong(8.ToString()); divisor1 = divisor1.Multiply(new VeryLong(n.ToString())).Add(new VeryLong(1.ToString())); summand1 = summand1.DivideBy(divisor1, numberOfDigits); VeryLong subtrahend2 = new VeryLong(2.ToString()); VeryLong divisor2 = new VeryLong(8.ToString()); divisor2 = divisor2.Multiply(new VeryLong(n.ToString())).Add(new VeryLong(4.ToString())); subtrahend2 = subtrahend2.DivideBy(divisor2, numberOfDigits); VeryLong subtrahend3 = new VeryLong(1.ToString()); VeryLong divisor3 = new VeryLong(8.ToString()); divisor3 = divisor3.Multiply(new VeryLong(n.ToString())).Add(new VeryLong(5.ToString())); subtrahend3 = subtrahend3.DivideBy(divisor3, numberOfDigits); VeryLong subtrahend4 = new VeryLong(1.ToString()); VeryLong divisor4 = new VeryLong(8.ToString()); divisor4 = divisor4.Multiply(new VeryLong(n.ToString())).Add(new VeryLong(6.ToString())); subtrahend4 = subtrahend4.DivideBy(divisor4, numberOfDigits); VeryLong sum = summand1.Subtract(subtrahend2).Subtract(subtrahend3).Subtract(subtrahend4); VeryLong term = sum.Multiply(factor); term.LimitPrecisionTo(numberOfDigits); return(term); }
public static VeryLong RemoveDecimalPlaces(VeryLong number) { return(new VeryLong(number.ToString().Replace(".", ""))); }
public static VeryLong Pi(int numberOfDigits) { VeryLong factor = new VeryLong(1.ToString()); int additionalCalcDigits = 10; int additionalLimitDigits = 0; VeryLong pi = new VeryLong("0"); if (_piAlgorithm == PiAlgorithm.BBP) { pi = GetStartValueBBP(numberOfDigits + additionalCalcDigits); // BBP } else if (_piAlgorithm == PiAlgorithm.Euler) { pi = new VeryLong("3"); // Euler } VeryLong limit = new VeryLong("0." + VeryLong.GetZeros(numberOfDigits + additionalLimitDigits) + "1" + VeryLong.GetZeros(additionalCalcDigits - additionalLimitDigits - 1)); int i = 0; StartTime(); while (true) { i++; VeryLong term = new VeryLong("0"); if (_piAlgorithm == PiAlgorithm.BBP) { term = GetPiTermBBP(i, numberOfDigits + additionalCalcDigits, ref factor); } else if (_piAlgorithm == PiAlgorithm.Euler) { term = GetPiTermEuler(i, numberOfDigits + additionalCalcDigits); } if (!term.IsLargerOrEqual(limit)) { Console.WriteLine("limit reached:"); Console.WriteLine("Term: " + term.ToString()); Console.WriteLine("limit: " + limit.ToString()); PrintTime(); break; } if (_piAlgorithm == PiAlgorithm.BBP) // BBP { pi = pi.Add(term); } else if (_piAlgorithm == PiAlgorithm.Euler) { if (i % 2 == 1) { pi = pi.Add(term); } else { pi = pi.Subtract(term); } } if (i % 10 == 0) { Console.WriteLine(); Console.WriteLine("Term " + i); Console.WriteLine("Pi: " + pi.ToString()); Console.WriteLine("Term: " + term.ToString()); Console.WriteLine("limit: " + limit.ToString()); PrintTime(); } else if (i % 1 == 0) { Console.Write("."); } } VeryLong piCorrectDigits = new VeryLong(pi.ToString().Remove(numberOfDigits + 2)); return(piCorrectDigits); }
public void RemoveLeadingZeros() { _integerString = VeryLong.RemoveLeadingZeros(_integerString); }
static void Main(string[] args) { for (int i = 0; i < 5; i++) { Console.WriteLine("Enter a calculation like '1+2' or enter 'pi'. Operations are + - * /. Numbers are integers of any size."); string input = Console.ReadLine(); if (input == "pi") { Console.WriteLine("Enter the number of digits you want."); string digitsString = Console.ReadLine(); int numberDigits = 0; if (int.TryParse(digitsString, out numberDigits)) { string pi = VeryLongMath.Pi(numberDigits).ToString(); Console.WriteLine("Pi is: " + pi.ToString()); } else { Console.WriteLine("invalid number."); } continue; } if (input == "sqrt") { int numberDigits; VeryLong number; Console.WriteLine("Square root of?"); string numberString = Console.ReadLine(); Console.WriteLine("number of digits?"); string digitsString = Console.ReadLine(); if (int.TryParse(digitsString, out numberDigits)) { number = new VeryLong(numberString); string sqrt = VeryLongMath.Sqrt(number, numberDigits).ToString(); Console.WriteLine("Sqrt of " + numberString + " is: " + sqrt.ToString()); } else { Console.WriteLine("invalid number."); } } string[] parts = input.Split(new char[] { '+', '-', '*', '/' }); if (parts.Length != 2) { Console.WriteLine("invalid input."); continue; } VeryLong number0 = new VeryLong(parts[0]); VeryLong number1 = new VeryLong(parts[1]); if (input.Contains('+')) { Console.WriteLine(number0.Add(number1).ToString()); } else if (input.Contains('*')) { Console.WriteLine(number0.Multiply(number1).ToString()); } else if (input.Contains('-')) { Console.WriteLine(number0.Subtract(number1).ToString()); } else if (input.Contains('/')) { VeryLong remainder; VeryLong quotient = number0.DivideBy(number1, out remainder); Console.WriteLine(quotient.ToString() + " Remainder: " + remainder); VeryLong quotientWithDecimal = number0.DivideBy(number1, 100); Console.WriteLine(quotientWithDecimal.ToString()); } else { Console.WriteLine("Please enter a valid operation..."); } } Console.ReadLine(); }