public static BigRational operator *(BigRational num1, BigRational num2) { // a/b * c/d = ac/bd BigRational retVal = new BigRational(num1.Numerator * num2.Numerator, num1.Denominator * num2.Denominator); retVal.Reduce(); return retVal; }
/// <summary> /// Computes pi to the specified number of digits using the Machin Formula. /// </summary> /// <param name="numDigits">The number of digits to which pi should be calculated.</param> /// <returns></returns> public static BigRational GetPi(BigInteger numDigits) { // pi = 16 arctan(1/5) − 4 arctan(1/239) BigRational oneFifth = new BigRational(1,5); BigRational oneTwoThirtyNine = new BigRational(1, 239); BigRational arcTanOneFifth = PiCalc.ArcTangent(oneFifth, PiCalc.GetConversionIterations(numDigits + 1, oneFifth)); // Start computing BigRational arcTanOneTwoThirtyNine = PiCalc.ArcTangent(oneTwoThirtyNine, PiCalc.GetConversionIterations(numDigits + 1, oneTwoThirtyNine)); return (arcTanOneFifth * 16) - (arcTanOneTwoThirtyNine * 4); }
/// <summary> /// Calculates an inverse tangent (arctan). /// </summary> /// <param name="input">The number of which the arctan should be computed.</param> /// <param name="iterations">The number of iterations of arctangent to compute.</param> /// <returns></returns> public static BigRational ArcTangent(BigRational input, BigInteger iterations) { BigRational retVal = input; for (BigInteger i = 1; i < iterations; i++) { // arctan(x) = x - x^3/3 + x^5/5 ... // = summation(n->infinity) (-1)^(n) * x^(2n+1)/(2n+1) BigRational powRat = input.Pow((2 * i) + 1); retVal += new BigRational(powRat.Numerator * (BigInteger)Math.Pow(-1d, (double)(i)), ((2 * i) + 1) * powRat.Denominator); // Code representation of the above formula. if (i % 100 == 0) { Console.WriteLine("ArcTangent {0}: {1}/{2} iterations complete.", input, i, iterations); // Status update. } } return retVal; }
/// <summary> /// Determines the number of iterations that must be /// </summary> /// <param name="digits">The number of correct digits </param> /// <returns></returns> public static BigInteger GetConversionIterations(BigInteger digits, BigRational q) { // http://turner.faculty.swau.edu/mathematics/materialslibrary/pi/calterms.html // iterations ~= digits / (2 log10 (1/number to arctan)) return (BigInteger)((double)digits / (2 * Math.Log10((double)q.GetReciprocal()))); }
// Operator overloading public static BigRational operator +(BigRational num1, BigRational num2) { if (num1.Denominator == num2.Denominator) { // The denominators are the same; just add the numerators and return. return new BigRational(num1.Numerator + num2.Numerator, num1.Denominator); } else { // Make the denominator the same, reduce it, and return it. BigRational retval = new BigRational ((num1.Numerator * num2.Denominator) + (num2.Numerator * num1.Denominator), num1.Denominator * num2.Denominator); retval.Reduce(); return retval; } }
// I don't want to call it scalar multiplication... but it's scalar multiplication if you consider the BigRational a 1x2 matrix. public static BigRational operator *(BigRational num1, BigInteger num2) { BigRational retVal = new BigRational(num1.Numerator * num2, num1.Denominator); retVal.Reduce(); return retVal; }
/// <summary> /// Returns the BigRational raised to the specified power. /// </summary> /// <param name="power">An integer greater than or equal to one.</param> /// <returns></returns> public BigRational Pow(BigInteger power) { // Error checking if (power < 1) throw new ArgumentException("BigRational.Pow only supports integer powers greater than or equal to one."); BigRational retVal = new BigRational(Numerator, Denominator); // Create a copy of the current BigRational for (BigInteger i = 1; i < power; i++) // Multiply the copy by itself power - 1 number of times { retVal.Numerator *= Numerator; retVal.Denominator *= Denominator; } retVal.Reduce(); return retVal; }
public static BigRational operator -(BigRational num1, BigRational num2) { // Same as + but we subtract here... if (num1.Denominator == num2.Denominator) { // The denominators are the same; just add the numerators and return. return new BigRational(num1.Numerator - num2.Numerator, num1.Denominator); } else { // Make the denominator the same, reduce it, and return it. BigRational retval = new BigRational((num1.Numerator * num2.Denominator) - (num2.Numerator * num1.Denominator), num1.Denominator * num2.Denominator); retval.Reduce(); return retval; } }