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

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