예제 #1
0
        public BigNumber Sqrt()
        {
            BigNumber res = 0;

            BigNumber.Sqrt(this, res, numDefaultPlaces);
            return(res);
        }
예제 #2
0
        public BigNumber Sqrt(int places)
        {
            BigNumber res = 0;

            BigNumber.Sqrt(this, res, places);
            return(res);
        }
        /****************************************************************************/

        /*
         *      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);
        }
예제 #4
0
        /****************************************************************************/

        /*
         *	define a notation for a function 'R' :
         *
         *
         *
         *                                    1
         *      R (a0, b0)  =  ------------------------------
         *
         *                          ----
         *                           \
         *                            \     n-1      2    2
         *                      1  -   |   2    *  (a  - b )
         *                            /              n    n
         *                           /
         *                          ----
         *                         n >= 0
         *
         *
         *      where a, b are the classic AGM iteration :
         *
         *
         *      a    =  0.5 * (a  + b )
         *       n+1            n    n
         *
         *
         *      b    =  sqrt(a  * b )
         *       n+1          n    n
         *
         *
         *
         *      define a variable 'c' for more efficient computation :
         *
         *                                      2     2     2
         *      c    =  0.5 * (a  - b )    ,   c  =  a  -  b
         *       n+1            n    n          n     n     n
         *
         */

        /****************************************************************************/
        static void     LogAGMRFunc(BigNumber aa, BigNumber bb, BigNumber rr, int places)
        {
            BigNumber tmp1, tmp2, tmp3, tmp4, tmpC2, sum, pow_2, tmpA0, tmpB0;
            int       tolerance, dplaces;

            tmpA0 = new BigNumber();
            tmpB0 = new BigNumber();
            tmpC2 = new BigNumber();
            tmp1  = new BigNumber();
            tmp2  = new BigNumber();
            tmp3  = new BigNumber();
            tmp4  = new BigNumber();
            sum   = new BigNumber();
            pow_2 = new BigNumber();

            tolerance = places + 8;
            dplaces   = places + 16;

            BigNumber.Copy(aa, tmpA0);
            BigNumber.Copy(bb, tmpB0);
            BigNumber.Copy(BigNumber.BN_OneHalf, pow_2);

            BigNumber.Mul(aa, aa, tmp1);                    /* 0.5 * [ a ^ 2 - b ^ 2 ] */
            BigNumber.Mul(bb, bb, tmp2);
            BigNumber.Sub(tmp1, tmp2, tmp3);
            BigNumber.Mul(BigNumber.BN_OneHalf, tmp3, sum);

            while (true)
            {
                BigNumber.Sub(tmpA0, tmpB0, tmp1);               /* C n+1 = 0.5 * [ An - Bn ] */
                BigNumber.Mul(BigNumber.BN_OneHalf, tmp1, tmp4); /* C n+1 */
                BigNumber.Mul(tmp4, tmp4, tmpC2);                /* C n+1 ^ 2 */

                /* do the AGM */

                BigNumber.Add(tmpA0, tmpB0, tmp1);
                BigNumber.Mul(BigNumber.BN_OneHalf, tmp1, tmp3);

                BigNumber.Mul(tmpA0, tmpB0, tmp2);
                BigNumber.Sqrt(tmp2, tmpB0, dplaces);

                BigNumber.Round(tmp3, tmpA0, dplaces);

                /* end AGM */

                BigNumber.Mul(BigNumber.Two, pow_2, tmp2);
                BigNumber.Copy(tmp2, pow_2);

                BigNumber.Mul(tmpC2, pow_2, tmp1);
                BigNumber.Add(sum, tmp1, tmp3);

                if ((tmp1.signum == 0) || ((-2 * tmp1.exponent) > tolerance))
                {
                    break;
                }

                BigNumber.Round(tmp3, sum, dplaces);
            }

            BigNumber.Sub(BigNumber.One, tmp3, tmp4);
            BigNumber.Reziprocal(tmp4, rr, places);
        }
예제 #5
0
        public static void DoTest()
        {
            BigNumber A = 0, B = 0, C = 0;
            BigNumber PI = new BigNumber();

            // assignment by string
            A = "12345";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            // assignment from hexadecimal string
            A = "0xff";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            A = "0x1ff";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            A = "0x123456789";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            A = "0xFeDcBafedcba";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            // assignment from binary string
            A = "%10001000";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            A = "%11011011100111000111000111100011010101010101";
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            // assignment by double
            A = 123.45;
            B = 0.12345;
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");

            // assignment by string in exponential form x = a*10^y. 10E3 = 10*10^^3 = 10000
            A = "10E3";     // 10E3 = 10*10^3 = 10000
            B = "1E4";      // 1E4  =  1*10^4 = 10000
            C = 10000;
            Console.WriteLine("assigned value was: " + A.ToFullString() + "(" + A.ToString() + ")");
            Console.WriteLine("10000 = " + A.ToFullString() + " = " + B.ToFullString() + " = " + C.ToFullString());

            A = 1; B = 2; C = 0;
            C = A + B;
            Console.WriteLine("the result of " + A.ToFullString() + "+" + B.ToFullString() + "=" + C.ToFullString());
            // addition of BigNumber + double
            C = A + 3.2;
            // addition of double + BigNumber
            C = 3.1 + B;
            A = "5.141592"; B = "2.91827";
            C = A - B;
            Console.WriteLine("the result of " + A.ToFullString() + "-" + B.ToFullString() + "=" + C.ToFullString());

            C = A * B;
            Console.WriteLine("the result of " + A.ToFullString() + "*" + B.ToFullString() + "=" + C.ToFullString());
            A = 5.0; B = 3.0;
            C = A * B;
            Console.WriteLine("the result of " + A.ToFullString() + "*" + B.ToFullString() + "=" + C.ToFullString());

            A = 4; B = 0.5;
            C = A.Pow(B);
            Console.WriteLine("the result of " + A.ToFullString() + " pow " + B.ToFullString() + "=" + C.ToFullString());

            A = 0.5; B = "5E-1";
            C = A.Pow(B, 16);
            Console.WriteLine("the result of " + A.ToFullString() + " pow " + B.ToFullString() + "=" + C.ToFullString());

            A = "1e3"; // "10E2"; //   "1E3 = 1000";
            C = A.Log10();
            Console.WriteLine("the result of " + A.ToFullString() + " Log10 =" + C.ToFullString());

            A = "10E3"; B = "1E4"; C = 10000;

            A = BigNumber.BN_E;
            C = A.Log();
            Console.WriteLine("the result of " + A.ToString() + " Log =" + C.ToFullString());

            A = 3.0;
            C = A.Rez();
            Console.WriteLine("the result of " + A.ToString() + " Rez =" + C.ToFullString());

            int NumPlaces = 4;

            A = 1.53456;
            C = A.Round(NumPlaces);
            Console.WriteLine("the result of " + A.ToString() + " Round(" + NumPlaces + ") =" + C.ToFullString());

            NumPlaces = 2;
            C         = A.Round(NumPlaces);
            Console.WriteLine("the result of " + A.ToString() + " Round(" + NumPlaces + ") =" + C.ToFullString());

            NumPlaces = 0;
            C         = A.Round(NumPlaces);
            Console.WriteLine("the result of " + A.ToString() + " Round(" + NumPlaces + ") =" + C.ToFullString());

            NumPlaces = 16;
            A         = 2.0;
            C         = A.Sqrt(NumPlaces);
            Console.WriteLine("the result of " + A.ToString() + " Sqrt(" + NumPlaces + ") =" + C.ToFullString());

            A = 1.0; B = 0;
            try
            {
                C = A / B;
            }
            catch (BigNumberException ex)
            {
                Console.WriteLine("Exception in operation: " + ex.Message);
            }

            A = 1.0;
            for (int i = 1; i <= 1000; i++)
            {
                A = A * i;
            }

            Console.WriteLine("the result of 1000!=" + A.ToFullString());
            A = A.Round(numDefaultPlaces);
            Console.WriteLine("the result of 1000!=" + A.ToString());

            DateTime before = DateTime.Now;

            NumPlaces = 5000;
            CalculatePiAGM(PI, NumPlaces);

            TimeSpan ts = DateTime.Now - before;

            Console.WriteLine("time for " + NumPlaces + " digits of PI: " + ts.TotalMilliseconds + "[ms]");
            Console.WriteLine(PI.ToFullString());

            Console.WriteLine("Press 'x' key to quit test");
            //while (true)
            //{
            //    ConsoleKeyInfo i = Console.ReadKey();
            //    if (i.KeyChar == 'x') break;
            //}
        }