Exemplo n.º 1
0
        public MainWindow()
        {
            InitializeComponent();
            calc.times = new int[3];
            //初始化,存1、2、4、根号2的大数表示
            calc.one  = new bigNum("1");
            calc.two  = new bigNum("2");
            calc.four = new bigNum("4");

            calc.sqrt2 = bigNum.sqrt(2);
            //calc.sqrt2.show();

            /*
             * 计算ln2
             */
            bigNum sqrt2_1 = calc.sqrt2 - calc.one;

            calc.ln2 = new bigNum("0");
            bigNum an = new bigNum(sqrt2_1);

            for (int i = 1; i <= 300; ++i)
            {
                calc.ln2 = calc.ln2 + an / (new bigNum(i.ToString()));
                an       = an * sqrt2_1;
                an.neg   = (i % 2 == 1 ? true : false);
            }
            calc.ln2 = calc.ln2 * calc.two;
            //calc.ln2.show();
        }
Exemplo n.º 2
0
        /*
         * 大数数字加法
         */
        private static bigNum plus(bigNum b1, bigNum b2)
        {
            bigNum bn1 = new bigNum(b1), bn2 = new bigNum(b2), ans = new bigNum();

            if (bn1.dot > bn2.dot)
            {
                for (int i = bn2.cnt - 1; i >= 0; --i)
                {
                    bn2.num[i + bn1.dot - bn2.dot] = bn2.num[i];
                    bn2.num[i] = 0;
                }
                bn2.cnt += bn1.dot - bn2.dot;
                bn2.dot  = bn1.dot;
            }
            else if (bn1.dot < bn2.dot)
            {
                for (int i = bn1.cnt - 1; i >= 0; --i)
                {
                    bn1.num[i + bn2.dot - bn1.dot] = bn1.num[i];
                    bn1.num[i] = 0;
                }
                bn1.cnt += bn2.dot - bn1.dot;
                bn1.dot  = bn2.dot;
            }
            else
            {
            }
            ans.cnt = bn1.cnt > bn2.cnt ? bn1.cnt : bn2.cnt;
            ans.dot = bn1.dot;
            for (int i = 0; i < ans.cnt; ++i)
            {
                ans.num[i] = bn1.num[i] + bn2.num[i];
            }
            //进位
            for (int i = 0; i < ans.cnt; ++i)
            {
                if (ans.num[i] >= mod)
                {
                    ans.num[i + 1] += ans.num[i] / mod;
                    ans.num[i]     %= mod;
                    if (i == ans.cnt - 1)
                    {
                        ++ans.cnt;
                    }
                }
            }
            if (ans.cnt > maxlen)
            {
                int delta = ans.cnt - maxlen;
                for (int i = 0; i < maxlen; ++i)
                {
                    ans.num[i]         = ans.num[i + delta];
                    ans.num[i + delta] = 0;
                }
                ans.dot -= delta;
                ans.cnt  = maxlen;
            }
            return(ans);
        }
Exemplo n.º 3
0
        /*
         * 大数除法
         */
        public static bigNum operator /(bigNum b1, bigNum b2)
        {
            bigNum ans = new bigNum("0");
            bigNum bn1 = new bigNum(b1), bn2 = new bigNum(b2);

            int[] num_a = bn1.num, num_b = bn2.num;
            int   len1 = bn1.cnt, len2 = bn2.cnt;

            for (int i = len1 - 1; i >= 0; --i)
            {
                num_a[i + maxlen * 2 - len1] = num_a[i];
                num_a[i] = 0;
            }
            len1 = maxlen * 2;
            int nTimes = len1 - len2;

            for (int i = len2 - 1; i >= 0; --i)
            {
                num_b[i + nTimes] = num_b[i];
                num_b[i]          = 0;
            }
            len2 = len1;
            int nTemp;

            for (int i = 0; i <= nTimes; ++i)
            {
                while ((nTemp = SubStract(num_a, num_b, len1, len2, i)) >= 0)
                {
                    len1 = nTemp;
                    ans.num[nTimes - i]++;
                }
                if (len1 == len2 - i && num_a[len1 - 1] == 0)
                {
                    len1--;
                }
            }
            ans.dot = 2 * maxlen - (bn1.cnt - bn1.dot) - bn2.dot;
            ans.cnt = len2;
            while (ans.num[ans.cnt - 1] == 0 && ans.cnt > ans.dot + 1)
            {
                ans.cnt--;
            }
            if (ans.cnt > maxlen)
            {
                int delta = ans.cnt - maxlen;
                for (int i = 0; i < maxlen; ++i)
                {
                    ans.num[i]         = ans.num[i + delta];
                    ans.num[i + delta] = 0;
                }
                ans.dot -= delta;
                ans.cnt  = maxlen;
            }
            ans.neg = bn1.neg ^ bn2.neg;
            return(ans);
        }
Exemplo n.º 4
0
 public bigNum(bigNum bn)//由大数初始化
 {
     neg = bn.neg;
     cnt = bn.cnt;
     dot = bn.dot;
     num = new int[1010];
     for (int i = 0; i < cnt; ++i)
     {
         num[i] = bn.num[i];
     }
 }
Exemplo n.º 5
0
 /*
  * 整数开根号
  */
 public static bigNum sqrt(int xx)
 {
     if (xx > 0)
     {
         bool     flag = false;
         bigNum   x    = new bigNum(xx.ToString());
         bigNum[] a    = new bigNum[2];
         a[1] = new bigNum("1");
         bigNum delta;
         bool   loop = true;
         while (loop)
         {
             loop = false;
             if (!flag)
             {
                 a[0] = (a[1] + x / a[1]) / calc.two;
             }
             else
             {
                 a[1] = (a[0] + x / a[0]) / calc.two;
             }
             flag  = !flag;
             delta = a[1] - a[0];
             for (int j = delta.cnt - 1; j >= delta.dot; --j)
             {
                 if (delta.num[j] != 0)
                 {
                     loop = true;
                     break;
                 }
             }
             if (!loop)
             {
                 for (int j = delta.dot - 1; j >= delta.dot - 500 && j >= 0; --j)
                 {
                     if (delta.num[j] != 0)
                     {
                         loop = true;
                         break;
                     }
                 }
             }
         }
         return(flag ? a[1] : a[0]);
     }
     return(new bigNum("0"));
 }
Exemplo n.º 6
0
        /*
         * 根据要求精度四舍五入
         */
        public bigNum round(bigNum bn, int acc)
        {
            bigNum ans = new bigNum(bn);

            if (ans.dot <= acc)
            {
                for (int i = ans.cnt - 1; i >= 0; --i)
                {
                    ans.num[i + acc - ans.dot] = ans.num[i];
                    ans.num[i] = 0;
                }
                ans.cnt += acc - ans.dot;
                ans.dot  = acc;
            }
            else
            {
                if (ans.num[ans.dot - acc - 1] >= 5)
                {
                    ans.num[ans.dot - acc] += 1;
                }
                for (int i = ans.dot - acc; i < ans.cnt; ++i)
                {
                    if (ans.num[i] >= mod)
                    {
                        ans.num[i + 1] += ans.num[i] / mod;
                        ans.num[i]     %= mod;
                        if (i == ans.cnt - 1)
                        {
                            ans.cnt++;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }
            return(ans);
        }
Exemplo n.º 7
0
        /*
         * 大数乘法
         */
        public static bigNum operator *(bigNum b1, bigNum b2)
        {
            bigNum ans = new bigNum();

            for (int i = 0; i < b1.cnt; ++i)
            {
                for (int j = 0; j < b2.cnt; ++j)
                {
                    ans.num[i + j] += b1.num[i] * b2.num[j];
                }
            }
            ans.cnt = b1.cnt + b2.cnt - 1;
            ans.dot = b1.dot + b2.dot;
            for (int i = 0; i < ans.cnt; ++i)
            {
                if (ans.num[i] >= mod)
                {
                    ans.num[i + 1] += ans.num[i] / mod;
                    ans.num[i]     %= mod;
                    if (i == ans.cnt - 1)
                    {
                        ++ans.cnt;
                    }
                }
            }
            if (ans.cnt > maxlen)
            {
                int delta = ans.cnt - maxlen;
                for (int i = 0; i < maxlen; ++i)
                {
                    ans.num[i]         = ans.num[i + delta];
                    ans.num[i + delta] = 0;
                }
                ans.dot -= delta;
                ans.cnt  = maxlen;
            }
            return(ans);
        }
Exemplo n.º 8
0
        /*
         * 大数带符号减法
         */
        public static bigNum operator -(bigNum b1, bigNum b2)
        {
            bigNum ans = new bigNum();

            if ((b1.neg ^ b2.neg))//符号不同,数字相加,符号跟随被减数
            {
                ans     = plus(b1, b2);
                ans.neg = b1.neg;
            }
            else//符号相同,数字相减,
            {
                if (b1 >= b2)
                {
                    ans     = minus(b1, b2);
                    ans.neg = b1.neg;
                }
                else
                {
                    ans     = minus(b2, b1);
                    ans.neg = !b1.neg;
                }
            }

            if (ans.cnt > maxlen)
            {
                int delta = ans.cnt - maxlen;
                for (int i = 0; i < maxlen; ++i)
                {
                    ans.num[i]         = ans.num[i + delta];
                    ans.num[i + delta] = 0;
                }
                ans.dot -= delta;
                ans.cnt  = maxlen;
            }

            return(ans);
        }
Exemplo n.º 9
0
        /*
         * 大数数字减法
         */
        private static bigNum minus(bigNum b1, bigNum b2)
        {
            bigNum bn1 = new bigNum(b1), bn2 = new bigNum(b2), ans = new bigNum();

            if (bn1.dot > bn2.dot)
            {
                for (int i = bn2.cnt - 1; i >= 0; --i)
                {
                    bn2.num[i + bn1.dot - bn2.dot] = bn2.num[i];
                    bn2.num[i] = 0;
                }
                bn2.cnt += bn1.dot - bn2.dot;
                bn2.dot  = bn1.dot;
            }
            else if (bn1.dot < bn2.dot)
            {
                for (int i = bn1.cnt - 1; i >= 0; --i)
                {
                    bn1.num[i + bn2.dot - bn1.dot] = bn1.num[i];
                    bn1.num[i] = 0;
                }
                bn1.cnt += bn2.dot - bn1.dot;
                bn1.dot  = bn2.dot;
            }
            else
            {
            }
            ans.cnt = bn1.cnt > bn2.cnt ? bn1.cnt : bn2.cnt;
            ans.dot = bn1.dot;
            for (int i = 0; i < ans.cnt; ++i)
            {
                ans.num[i] = bn1.num[i] - bn2.num[i];
            }
            //借位
            for (int i = 0; i < ans.cnt; ++i)
            {
                if (ans.num[i] < 0)
                {
                    ans.num[i + 1] += ans.num[i] / mod;
                    ans.num[i]     %= mod;
                    if (ans.num[i] < 0)
                    {
                        ans.num[i + 1]--;
                        ans.num[i] += mod;
                    }
                }
            }
            while (ans.num[ans.cnt - 1] == 0 && ans.cnt > ans.dot + 1)
            {
                ans.cnt--;
            }
            if (ans.cnt > maxlen)
            {
                int delta = ans.cnt - maxlen;
                for (int i = 0; i < maxlen; ++i)
                {
                    ans.num[i]         = ans.num[i + delta];
                    ans.num[i + delta] = 0;
                }
                ans.dot -= delta;
                ans.cnt  = maxlen;
            }
            return(ans);
        }
Exemplo n.º 10
0
        /*
         *      a. Taylor展开(最佳或近似最佳逼近);
         *      b. 数值积分;
         *      c. 非Taylor展开的函数逼近方法(选作);
         */

        private void button_Click(object sender, RoutedEventArgs e)
        {
            if (accuracy.Text == "")
            {
                MessageBox.Show("请输入精度");
                return;
            }
            if (num.Text == "")
            {
                MessageBox.Show("请输入x");
                return;
            }
            Stopwatch stopwatch = new Stopwatch();

            for (int i = 0; i < accuracy.Text.Length; ++i)
            {
                if (accuracy.Text[i] < '0' || accuracy.Text[i] > '9')
                {
                    MessageBox.Show("精度请输入有效正整数");
                    return;
                }
            }
            acc = Convert.ToInt32(accuracy.Text);

            if (acc >= 50)
            {
                MessageBox.Show("精度建议小于50");
                return;
            }
            if (acc < 0)
            {
                MessageBox.Show("结果小数位数大于等于0");
                return;
            }

            int cntdot = 0;

            for (int i = 0; i < num.Text.Length; ++i)
            {
                if (num.Text[i] < '0' || num.Text[i] > '9')
                {
                    if (num.Text[i] == '.')
                    {
                        cntdot++;
                        if (cntdot > 1)
                        {
                            MessageBox.Show("请输入有效x");
                            return;
                        }
                    }
                    else
                    {
                        MessageBox.Show("请输入有效x");
                        return;
                    }
                }
            }
            bigNum input = new bigNum(num.Text);

            if (input < calc.one)
            {
                MessageBox.Show("请输入不小于1的x");
                return;
            }


            /*
             * Taylor展开段
             */
            stopwatch.Reset();
            stopwatch.Start();
            bigNum halfTaylorAns = calc.halfTaylor(num.Text, acc);

            halfTaylor.Text = (calc.round(halfTaylorAns, acc)).show(acc);
            stopwatch.Stop();
            halfTaylorTime.Text  = stopwatch.ElapsedMilliseconds.ToString() + "ms";
            halfTaylorTimes.Text = calc.times[0].ToString();

            /*
             * Romberg数值积分段
             */
            stopwatch.Reset();
            stopwatch.Start();
            bigNum rombergAns = calc.romberg(num.Text, acc);

            romberg.Text = (calc.round(rombergAns, acc)).show(acc);
            stopwatch.Stop();
            rombergTime.Text  = stopwatch.ElapsedMilliseconds.ToString() + "ms";
            rombergTimes.Text = calc.times[1].ToString();

            /*
             * 有理逼近段
             */
            stopwatch.Reset();
            stopwatch.Start();
            bigNum rationalAns = calc.rational(num.Text, acc);

            rational.Text = (calc.round(rationalAns, acc)).show(acc);
            stopwatch.Stop();
            rationalTime.Text  = stopwatch.ElapsedMilliseconds.ToString() + "ms";
            rationalTimes.Text = calc.times[2].ToString();
            //MessageBox.Show("Done!");
        }