public static BigNumber operator /(BigNumber c1, BigNumber c2) { BigNumber res = new BigNumber(); if (maxDoubleBigNumber == 0) { maxDoubleBigNumber = BigNumber.Parse(double.MaxValue.ToString("F0", globalCultureInfo)); minDoubleBigNumber = BigNumber.Parse(double.MinValue.ToString("F0", globalCultureInfo)); maxFloatBigNumber = BigNumber.Parse(float.MaxValue.ToString("F0", globalCultureInfo)); minFloatBigNumber = BigNumber.Parse(float.MinValue.ToString("F0", globalCultureInfo)); } if (c2 <= maxFloatBigNumber && c2 >= minFloatBigNumber) { float cTemp = 0; float.TryParse(c2.ToFullString().Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out cTemp); res = c1 / cTemp; } else if (c2 <= maxDoubleBigNumber && c2 >= minDoubleBigNumber) { double cTemp = 0; double.TryParse(c2.ToFullString().Replace(',', '.'), NumberStyles.Any, CultureInfo.InvariantCulture, out cTemp); res = c1 / cTemp; } else { BigNumber.Div(c1, c2, res); } return(res); }
static void M_log_solve_cubic(BigNumber nn, BigNumber rr, int places) { BigNumber tmp0, tmp1, tmp2, tmp3, guess; int ii, maxp, tolerance, local_precision; guess = new BigNumber(); tmp0 = new BigNumber(); tmp1 = new BigNumber(); tmp2 = new BigNumber(); tmp3 = new BigNumber(); BigNumber.M_get_log_guess(nn, guess); tolerance = -(places + 4); maxp = places + 16; local_precision = 18; ii = 0; while (true) { BigNumber.Exp(guess, tmp1, local_precision); BigNumber.Sub(tmp1, nn, tmp3); BigNumber.Add(tmp1, nn, tmp2); BigNumber.Div(tmp3, tmp2, tmp1, local_precision); BigNumber.Mul(BigNumber.Two, tmp1, tmp0); BigNumber.Sub(guess, tmp0, tmp3); if (ii != 0) { if (((3 * tmp0.exponent) < tolerance) || (tmp0.signum == 0)) { break; } } BigNumber.Round(tmp3, guess, local_precision); local_precision *= 3; if (local_precision > maxp) { local_precision = maxp; } ii = 1; } BigNumber.Round(tmp3, rr, places); }
/****************************************************************************/ /* * Calculate PI using the AGM (Arithmetic-Geometric Mean) * * Init : A0 = 1 * B0 = 1 / sqrt(2) * Sum = 1 * * Iterate: n = 1... * * * A = 0.5 * [ A + B ] * n n-1 n-1 * * * B = sqrt [ A * B ] * n n-1 n-1 * * * C = 0.5 * [ A - B ] * n n-1 n-1 * * * 2 n+1 * Sum = Sum - C * 2 * n * * * At the end when C is 'small enough' : * n * * 2 * PI = 4 * A / Sum * n+1 * * -OR- * * 2 * PI = ( A + B ) / Sum * n n * */ static private void CalculatePiAGM(BigNumber outv, int places) { int dplaces, nn; BigNumber tmp1 = new BigNumber(); BigNumber tmp2 = new BigNumber(); BigNumber a0 = new BigNumber(); BigNumber b0 = new BigNumber(); BigNumber c0 = new BigNumber(); BigNumber a1 = new BigNumber(); BigNumber b1 = new BigNumber(); BigNumber sum = new BigNumber(); BigNumber pow_2 = new BigNumber(); dplaces = places + 16; BigNumber.Copy(BigNumber.One, a0); BigNumber.Copy(BigNumber.One, sum); BigNumber.Copy(BigNumber.Four, pow_2); BigNumber.Sqrt(BigNumber.BN_OneHalf, b0, dplaces); while (true) { BigNumber.Add(a0, b0, tmp1); BigNumber.Mul(tmp1, BigNumber.BN_OneHalf, a1); BigNumber.Mul(a0, b0, tmp1); BigNumber.Sqrt(tmp1, b1, dplaces); BigNumber.Sub(a0, b0, tmp1); BigNumber.Mul(BigNumber.BN_OneHalf, tmp1, c0); BigNumber.Mul(c0, c0, tmp1); BigNumber.Mul(tmp1, pow_2, tmp2); BigNumber.Sub(sum, tmp2, tmp1); BigNumber.Round(tmp1, sum, dplaces); nn = -4 * c0.exponent; if (nn >= dplaces) { break; } BigNumber.Copy(a1, a0); BigNumber.Copy(b1, b0); BigNumber.Mul(pow_2, BigNumber.Two, tmp1); BigNumber.Copy(tmp1, pow_2); } BigNumber.Add(a1, b1, tmp1); BigNumber.Mul(tmp1, tmp1, tmp2); BigNumber.Div(tmp2, sum, tmp1, dplaces); BigNumber.Round(tmp1, outv, places); }
/****************************************************************************/ /* * calculate log (1 + x) with the following series: * * x * y = ----- ( |y| < 1 ) * x + 2 * * * [ 1 + y ] y^3 y^5 y^7 * log [-------] = 2 * [ y + --- + --- + --- ... ] * [ 1 - y ] 3 5 7 * */ static void M_log_near_1(BigNumber xx, BigNumber rr, int places) { BigNumber tmp0, tmp1, tmp2, tmpS, term; int tolerance, dplaces, local_precision; long m1; tmp0 = new BigNumber(); tmp1 = new BigNumber(); tmp2 = new BigNumber(); tmpS = new BigNumber(); term = new BigNumber(); tolerance = xx.exponent - (places + 6); dplaces = (places + 12) - xx.exponent; BigNumber.Add(xx, BigNumber.Two, tmp0); BigNumber.Div(xx, tmp0, tmpS, (dplaces + 6)); BigNumber.Copy(tmpS, term); BigNumber.Mul(tmpS, tmpS, tmp0); BigNumber.Round(tmp0, tmp2, (dplaces + 6)); m1 = 3L; while (true) { BigNumber.Mul(term, tmp2, tmp0); if ((tmp0.exponent < tolerance) || (tmp0.signum == 0)) { break; } local_precision = dplaces + tmp0.exponent; if (local_precision < 20) { local_precision = 20; } BigNumber.SetFromLong(tmp1, m1); BigNumber.Round(tmp0, term, local_precision); BigNumber.Div(term, tmp1, tmp0, local_precision); BigNumber.Add(tmpS, tmp0, tmp1); BigNumber.Copy(tmp1, tmpS); m1 += 2; } BigNumber.Mul(BigNumber.Two, tmpS, tmp0); BigNumber.Round(tmp0, rr, places); }
static private void M_raw_exp(BigNumber xx, BigNumber rr, int places) { BigNumber tmp0, digit, term; int tolerance, local_precision, prev_exp; long m1; tmp0 = new BigNumber(); term = new BigNumber(); digit = new BigNumber(); local_precision = places + 8; tolerance = -(places + 4); prev_exp = 0; BigNumber.Add(BigNumber.One, xx, rr); BigNumber.Copy(xx, term); m1 = 2L; while (true) { BigNumber.SetFromLong(digit, m1); BigNumber.Mul(term, xx, tmp0); BigNumber.Div(tmp0, digit, term, local_precision); BigNumber.Add(rr, term, tmp0); BigNumber.Copy(tmp0, rr); if ((term.exponent < tolerance) || (term.signum == 0)) { break; } if (m1 != 2L) { local_precision = local_precision + term.exponent - prev_exp; if (local_precision < 20) { local_precision = 20; } } prev_exp = term.exponent; m1++; } }
static public void Div(BigNumber aa, BigNumber bb, BigNumber rr) { int places = BigNumber.MaxDigits(aa, bb); BigNumber.Div(aa, bb, rr, places); }
static public void Reziprocal(BigNumber src, BigNumber dst, int places) { BigNumber.Div(BigNumber.One, src, dst, places); }