コード例 #1
0
ファイル: BigFloat.cs プロジェクト: jmcgonegal/CSEuler
        /// <summary>
        /// Division-based reciprocal, fastest for small precisions up to 15,000 bits.
        /// </summary>
        /// <returns>The reciprocal 1/this</returns>
        public BigFloat Reciprocal()
        {
            if (mantissa.Precision.NumBits >= 8192) return ReciprocalNewton();

            BigFloat reciprocal = new BigFloat(1u, mantissa.Precision);
            reciprocal.Div(this);
            return reciprocal;
        }
コード例 #2
0
ファイル: BigFloat.cs プロジェクト: jmcgonegal/CSEuler
 /// <summary>
 /// Divides two numbers and assigns the result to res.
 /// </summary>
 /// <param name="res">a pre-existing BigFloat to take the result</param>
 /// <param name="n1">the first number</param>
 /// <param name="n2">the second number</param>
 /// <returns>a handle to res</returns>
 public static BigFloat Div(BigFloat res, BigFloat n1, BigFloat n2)
 {
     res.Assign(n1);
     res.Div(n2);
     return res;
 }
コード例 #3
0
ファイル: BigFloat.cs プロジェクト: jmcgonegal/CSEuler
        /// <summary>
        /// Uses the Gauss-Legendre formula for pi
        /// Taken from http://en.wikipedia.org/wiki/Gauss%E2%80%93Legendre_algorithm
        /// </summary>
        /// <param name="numBits"></param>
        private static void CalculatePi(int numBits)
        {
            int bits = numBits + 32;
            //Precision extend taken out.
            PrecisionSpec normalPres = new PrecisionSpec(numBits, PrecisionSpec.BaseType.BIN);
            PrecisionSpec extendedPres = new PrecisionSpec(bits, PrecisionSpec.BaseType.BIN);

            if (scratch.Precision.NumBits != bits)
            {
                scratch = new BigInt(extendedPres);
            }

            //a0 = 1
            BigFloat an = new BigFloat(1, extendedPres);

            //b0 = 1/sqrt(2)
            BigFloat bn = new BigFloat(2, extendedPres);
            bn.Sqrt();
            bn.exponent--;

            //to = 1/4
            BigFloat tn = new BigFloat(1, extendedPres);
            tn.exponent -= 2;

            int pn = 0;

            BigFloat anTemp = new BigFloat(extendedPres);

            int iteration = 0;
            int cutoffBits = numBits >> 5;

            for (iteration = 0; ; iteration++)
            {
                //Save a(n)
                anTemp.Assign(an);

                //Calculate new an
                an.Add(bn);
                an.exponent--;

                //Calculate new bn
                bn.Mul(anTemp);
                bn.Sqrt();

                //Calculate new tn
                anTemp.Sub(an);
                anTemp.mantissa.SquareHiFast(scratch);
                anTemp.exponent += anTemp.exponent + pn + 1 - anTemp.mantissa.Normalise();
                tn.Sub(anTemp);

                anTemp.Assign(an);
                anTemp.Sub(bn);

                if (anTemp.exponent < -(bits - cutoffBits)) break;

                //New pn
                pn++;
            }

            an.Add(bn);
            an.mantissa.SquareHiFast(scratch);
            an.exponent += an.exponent + 1 - an.mantissa.Normalise();
            tn.exponent += 2;
            an.Div(tn);

            pi = new BigFloat(an, normalPres);
            piBy2 = new BigFloat(pi);
            piBy2.exponent--;
            twoPi = new BigFloat(pi, normalPres);
            twoPi.exponent++;
            piRecip = new BigFloat(an.Reciprocal(), normalPres);
            twoPiRecip = new BigFloat(piRecip);
            twoPiRecip.exponent--;
            //1/3 is going to be useful for sin.
            threeRecip = new BigFloat((new BigFloat(3, extendedPres)).Reciprocal(), normalPres);
        }
コード例 #4
0
ファイル: BigFloat.cs プロジェクト: jmcgonegal/CSEuler
 /// <summary>
 /// Divides two numbers and returns the result
 /// </summary>
 public static BigFloat Div(BigFloat n1, BigFloat n2)
 {
     BigFloat ret = new BigFloat(n1);
     ret.Div(n2);
     return ret;
 }