예제 #1
0
        static void Log10(BigNumber src, BigNumber dst, int places)
        {
            BigNumber tmp8    = new BigNumber();
            BigNumber tmp9    = new BigNumber();
            int       dplaces = places + 4;

            BigNumber.CheckLogPlaces(dplaces + 45);
            BigNumber.Log(src, tmp9, dplaces);
            BigNumber.Mul(tmp9, BN_lc_log10R, tmp8);
            BigNumber.Round(tmp8, dst, places);
        }
예제 #2
0
        static private void Exp(BigNumber src, BigNumber dst, int places)
        {
            BigNumber A = 0, B = 0, C = 0;
            int       dplaces, nn = 0, ii = 0;

            if (src.signum == 0)
            {
                BigNumber.Copy(BigNumber.One, dst);
                return;
            }

            if (src.exponent <= -3)
            {
                M_raw_exp(src, C, (places + 6));
                BigNumber.Round(C, dst, places);
                return;
            }

            if (M_exp_compute_nn(ref nn, A, src) != 0)
            {
                throw new BigNumberException("'Exp', Input too large, Overflow");
            }

            dplaces = places + 8;

            BigNumber.CheckLogPlaces(dplaces);
            BigNumber.Mul(A, BN_lc_log2, B);
            BigNumber.Sub(src, B, A);

            while (true)
            {
                if (A.signum != 0)
                {
                    if (A.exponent == 0)
                    {
                        break;
                    }
                }

                if (A.signum >= 0)
                {
                    nn++;
                    BigNumber.Sub(A, BN_lc_log2, B);
                    BigNumber.Copy(B, A);
                }
                else
                {
                    nn--;
                    BigNumber.Add(A, BN_lc_log2, B);
                    BigNumber.Copy(B, A);
                }
            }

            BigNumber.Mul(A, BN_exp_512R, C);

            M_raw_exp(C, B, dplaces);

            ii = 9;

            while (true)
            {
                BigNumber.Mul(B, B, C);
                BigNumber.Round(C, B, dplaces);

                if (--ii == 0)
                {
                    break;
                }
            }

            BigNumber.IntPow(dplaces, BigNumber.Two, nn, A);
            BigNumber.Mul(A, B, C);
            BigNumber.Round(C, dst, places);
        }
예제 #3
0
        static void Log(BigNumber src, BigNumber dst, int places)
        {
            BigNumber tmp0, tmp1, tmp2;
            int       mexp, dplaces;

            if (src.signum <= 0)
            {
                throw new BigNumberException(" 'Log', Negative argument");
            }

            tmp0 = new BigNumber();
            tmp1 = new BigNumber();
            tmp2 = new BigNumber();

            dplaces = places + 8;

            mexp = src.exponent;

            if (mexp == 0 || mexp == 1)
            {
                BigNumber.Sub(src, BigNumber.One, tmp0);

                if (tmp0.signum == 0)    /* is input exactly 1 ?? */
                {                        /* if so, result is 0    */
                    BigNumber.SetZero(dst);
                    return;
                }

                if (tmp0.exponent <= -4)
                {
                    M_log_near_1(tmp0, dst, places);
                    return;
                }
            }

            /* make sure our log(10) is accurate enough for this calculation */
            /* (and log(2) which is called from M_log_basic_iteration) */

            BigNumber.CheckLogPlaces(dplaces + 25);

            if (Math.Abs(mexp) <= 3)
            {
                M_log_basic_iteration(src, dst, places);
            }
            else
            {
                /*
                 *  use log (x * y) = log(x) + log(y)
                 *
                 *  here we use y = exponent of our base 10 number.
                 *
                 *  let 'C' = log(10) = 2.3025850929940....
                 *
                 *  then log(x * y) = log(x) + ( C * base_10_exponent )
                 */

                BigNumber.Copy(src, tmp2);

                mexp          = tmp2.exponent - 2;
                tmp2.exponent = 2;

                M_log_basic_iteration(tmp2, tmp0, dplaces);

                BigNumber.SetFromLong(tmp1, (long)mexp);
                BigNumber.Mul(tmp1, BN_lc_log10, tmp2);
                BigNumber.Add(tmp2, tmp0, tmp1);

                BigNumber.Round(tmp1, dst, places);
            }
        }