• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            /*
              Name: 高精度整數運算改進版
              Copyright:始發于goal00001111的專欄;允許自由轉載,但必須注明作者和出處
              Author: goal00001111
              Date: 15-12-08 08:18
              Description:
            高精度整數運算:加減乘除,乘方,階乘 。
            上次寫了一個用字符串存儲高精度整數的四則運算算法,雖然可以實現功能,但時間復雜度和空間復雜度都不夠理想,
            這次出了個改進版,將原來的用字符串存儲改成用整型數組存儲,而且改進了乘法,除法和乘方的算法,更快更高效!
            */
            #include<iostream>
            #include<string>

            using namespace std;

            const unsigned int MAX = 10000; //整型數組的最大長度
            const long long WIDTHMAX = 1000000000; //整型數組val[MAX]的元素上限
            const unsigned int WIDTH = 9;  //輸出整型數組val[MAX]的元素時的格式寬度,即整型數組val[MAX]的元素的最多位數

            typedef struct node
            {
                long long val[MAX]; //用來存儲高精度整數
                unsigned int size; //整型數組的實際長度
            } BigInt;

            BigInt StrToBigInt(string s);
            void PrintBigInt(const BigInt & a);
            int ComPareBigInt(const BigInt & a, const BigInt & b);
            BigInt MulBigInt(const BigInt & a, const BigInt & b);
            BigInt AddBigInt(const BigInt & a, const BigInt & b);
            BigInt SubBigInt(BigInt a, BigInt b);
            BigInt DivBigInt(const BigInt & a, const BigInt & b);
            BigInt FacBigInt(unsigned int n);
            void PowBigInt(BigInt & c, const BigInt & a, unsigned int n);
            void PowBigInt_2(BigInt & c, const BigInt & a, unsigned int n);
            BigInt HalfBigInt(BigInt a);

            int main()
            {
                string s;
                BigInt a, b, c;
               
                cin >> s;
                a = StrToBigInt(s);
                cin >> s;
                b = StrToBigInt(s);
               
                cout << "  ";
                PrintBigInt(a);
                cout << "+ ";
                PrintBigInt(b);
                c = AddBigInt(a, b);
                cout << "= ";
                PrintBigInt(c);
                cout << endl;
               
                cout << "  ";
                PrintBigInt(a);
                cout << "- ";
                PrintBigInt(b);
                c = SubBigInt(a, b);
                cout << "= ";
                PrintBigInt(c);
                cout << endl;
               
                cout << "  ";
                PrintBigInt(a);
                cout << "* ";
                PrintBigInt(b);
                c = MulBigInt(a, b);
                cout << "= ";
                PrintBigInt(c);
                cout << endl;
               
                cout << "  ";
                PrintBigInt(a);
                cout << "/ 2 " << endl;
                c = HalfBigInt(a);
                cout << "= ";
                PrintBigInt(c);
                cout << endl;
               
                cout << "  ";
                PrintBigInt(a);
                cout << "/ ";
                PrintBigInt(b);
                c = DivBigInt(a, b);
                cout << "= ";
                PrintBigInt(c);
                cout << endl;
               
                unsigned int n;
                cin >> n;
                //cout << n << "! = ";
            //    c = FacBigInt(n);
            //    PrintBigInt(c);
            //    cout << c.size << endl;
                 cout << endl;

                cout << "  ";
                PrintBigInt(a);
                cout << "^" << n << " = ";
                PowBigInt(c, a, n);
                PrintBigInt(c);
                cout << endl;
               
                cout << "  ";
                PrintBigInt(a);
                cout << "^" << n << " = ";
                PowBigInt_2(c, a, n);
                PrintBigInt(c);
                cout << endl;
               
                system("pause");
                return 0;
            }
            /*
            函數名稱:PrintBigInt
            函數功能:輸出用整型數組表示的高精度整數
            輸入參數:const BigInt & a:用整型數組表示的高精度整數
            輸出參數:無
            */
            void PrintBigInt(const BigInt & a)
            {
                cout << a.val[a.size-1];
                for (int i=a.size-2; i>=0; i--)
                {
                    unsigned w = WIDTHMAX / 10;
                    while (w > 0)
                    {
                        if (a.val[i] >= w)
                            break;
                        cout << 0;
                        w /= 10;
                    }
                    cout << a.val[i];
                }
                cout << endl;
            }
            /*
            函數名稱:StrToBigInt
            函數功能:把元素為數字的字符串轉換為用整型數組表示的高精度整數
            輸入參數:string s:存儲數字的字符串
            輸出參數:BigInt:返回用整型數組表示的高精度整數
            */
            BigInt StrToBigInt(string s)
            {
                BigInt a;
                a.size = 0;
                int i = s.size();
                unsigned long long sum = 0;
                while ( i>=WIDTH)
                {
                    for (int j=i-WIDTH; j<i; j++)
                        sum = sum * 10 + (s[j] - '0');
                    a.val[a.size++] = sum;
                    sum = 0;
                    i -= WIDTH;
                }
                if (i > 0)
                {
                    for (int j=0; j<i; j++)
                        sum = sum * 10 + (s[j] - '0');
                    a.val[a.size++] = sum;
                }
                return a;
            }
            /*
            函數名稱:AddBigInt
            函數功能:高精度整數加法
            輸入參數:const BigInt & a:用整型數組表示的高精度整數加數
                      const BigInt & b:用整型數組表示的高精度整數加數
            輸出參數:BigInt:返回用整型數組表示的高精度整數和
            */
            BigInt AddBigInt(const BigInt & a, const BigInt & b)
            {
                //逆序計算a+b,則從低位開始計算
                BigInt c;
                unsigned long long carry = 0;
                unsigned int i = 0;
                c.size = 0;
                while (i < a.size && i < b.size)
                {
                    c.val[c.size++] = (a.val[i] + b.val[i] + carry) % WIDTHMAX;
                    carry = (a.val[i] + b.val[i] + carry) / WIDTHMAX;
                    i++;
                }
                while (i < a.size)
                {
                    c.val[c.size++] =  (a.val[i] + carry) % WIDTHMAX;
                    carry = (a.val[i] + carry) / WIDTHMAX;
                    i++;
                }
                while (i < b.size)
                {
                    c.val[c.size++] =  (b.val[i] + carry) % WIDTHMAX;
                    carry = (b.val[i] + carry) / WIDTHMAX;
                    i++;
                }
                if (carry > 0)
                    c.val[c.size++] = carry;
                return c;
            }
            /*
            函數名稱:SubBigInt
            函數功能:高精度整數減法
            輸入參數:BigInt a:用整型數組表示的高精度整數被減數
                      BigInt b:用整型數組表示的高精度整數減數
            輸出參數:BigInt:返回用整型數組表示的高精度整數差
            */
            BigInt SubBigInt(BigInt a, BigInt b)
            {
                BigInt c;
                c.size = 0;
                if (ComPareBigInt(a, b) == 0)
                {
                    c.size = 1;
                    c.val[0] = 0;
                    return c;
                }
                bool flag = false;
                if (ComPareBigInt(a, b) < 0)//交換,并得到一個負號
                {
                    flag = true;
                    BigInt temp = a;
                    a = b;
                    b = temp;
                }
                unsigned int i = 0;
                while (i < b.size)
                {
                    if (a.val[i] >= b.val[i])
                         c.val[c.size++] = a.val[i] - b.val[i];
                    else
                    {
                        a.val[i+1] -= 1;
                        c.val[c.size++] = a.val[i] + WIDTHMAX - b.val[i];
                    }  
                    i++;
                }
                while (i < a.size)
                {
                    if (a.val[i] < 0)
                    {
                        a.val[i+1] -= 1;
                        a.val[i] += WIDTHMAX;
                    }
                    c.val[c.size++] = a.val[i];
                    i++;
                }
                //消除多余的高位0
                while (c.val[c.size-1] == 0)
                    c.size--;
                      
                if (flag)//如果是負數,加上負號
                    c.val[c.size-1] = -c.val[c.size-1];
                return c;
            }
            /*
            函數名稱:ComPareBigInt
            函數功能:比較兩個高精度整數的大小
            輸入參數:BigInt a:用整型數組表示的高精度整數被減數
                      BigInt b:用整型數組表示的高精度整數減數
            輸出參數:int:a > b返回1,a = b返回0,a < b返回-1
            */
            int ComPareBigInt(const BigInt & a, const BigInt & b)
            {
                if (a.size > b.size)
                    return 1;
                if (a.size < b.size)
                    return -1;
                   
                for (int i=a.size-1; i>=0; i--)
                {
                    if (a.val[i] > b.val[i])
                        return 1;
                    if (a.val[i] < b.val[i])
                        return -1;
                }
                return 0;
            }
            /*
            函數名稱:MulBigInt
            函數功能:高精度整數乘法
            輸入參數:const BigInt & a:用整型數組表示的高精度整數被乘數
                      const BigInt & b:用整型數組表示的高精度整數乘數
            輸出參數:BigInt:返回用整型數組表示的高精度整數乘積
            */
            BigInt MulBigInt(const BigInt & a, const BigInt & b)
            {
                if (a.size == 1 && a.val[0] == 0)
                    return a;
                if (b.size == 1 && b.val[0] == 0)
                    return b;
             
                BigInt c;
                for (int i=0; i<MAX; i++) //全部賦初值為0
                    c.val[i] = 0;
                for (int i=0, j=0; i<b.size; i++)
                {
                    for (j=0; j<a.size; j++)
                    {
                        c.val[i+j] += a.val[j] * b.val[i];
                        c.val[i+j+1] += c.val[i+j] / WIDTHMAX;
                        c.val[i+j] %= WIDTHMAX;
                    }
                    c.size = i + j;
                    if (c.val[c.size] != 0)//最高位有進位
                        c.size++;
                }
                return c;
            }
            /*
            老版本:
            BigInt MulBigInt2(const BigInt & a, const BigInt & b)
            {
                if (a.size == 1 && a.val[0] == 0)
                    return a;
                if (b.size == 1 && b.val[0] == 0)
                    return b;
             
                BigInt c, tc;
                unsigned long long carry = 0;
                c.size = 0;
                for (int i=0, j=0; i<b.size; i++)
                {
                    for (j=0; j<i; j++)//先在臨時和tc的低位補足0
                        tc.val[j] = 0;
                    carry = 0;
                    for (j=0; j<a.size; j++)
                    {
                        tc.val[i+j] = (a.val[j] * b.val[i] + carry) % WIDTHMAX;
                        carry = (a.val[j] * b.val[i] + carry) / WIDTHMAX;
                    }
                    tc.size = i + j;
                    if (carry > 0)
                        tc.val[tc.size++] = carry;
                    //累加到c中
                    c = AddBigInt(tc, c);
                }
                return c;
            }
            */

            /*
            函數名稱:FacBigInt
            函數功能:高精度整數階乘
            輸入參數:unsigned int n:正整數
            輸出參數:BigInt:返回用整型數組表示的高精度整數階乘
            */
            BigInt FacBigInt(unsigned int n)
            {
                BigInt s, c;
                c.size = s.size = 1;
                s.val[0] = 1;
                for (unsigned long long i=2; i<=n; i++)
                {
                    c.val[0] = i;
                    s = MulBigInt(s, c);
                }
                return s;
            }

            /*
            函數名稱:PowBigInt
            函數功能:遞歸高效算法求高精度整數冪
            輸入參數:BigInt & c:存儲高精度整數冪的整型數組
                      const BigInt & a:用整型數組表示的高精度整數底數
                      long long n:  指數
            */
            void PowBigInt(BigInt & c, const BigInt & a, unsigned int n)
            {
                if (n == 1)
                {
                    c = a;
                    return ;
                }
                if (n == 0 || (a.size == 1 && a.val[0] == 1))
                {
                    c.size = c.val[0] = 1;
                    return ; 
                }
               
                PowBigInt(c, a, n/2); //遞歸求高精度整數冪
               
                c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a)
                if (n % 2 == 1)      //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
                    c = MulBigInt(a, c);
            }

            /*
            函數名稱:PowBigInt_2
            函數功能:非遞歸高效算法求高精度整數冪
            輸入參數:BigInt & c:存儲高精度整數冪的整型數組
                      const BigInt & a:用整型數組表示的高精度整數底數
                      long long n:  指數
            */
            void PowBigInt_2(BigInt & c, const BigInt & a, unsigned int n)
            {
                int stack[MAX] = {0};
                int top = 0;
                while (n > 0) //利用一個棧來存儲n的狀態:奇數還是偶數
                {
                    stack[top++] = n % 2;
                    n /= 2;
                }
                c.size = c.val[0] = 1;
                for (int i=top-1; i>=0; i--)
                {
                    c = MulBigInt(c, c);  //a^n = a^(n/2)*a^(n/2)*f(a)
                    if (stack[i] == 1)   //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
                        c = MulBigInt(a, c);
                }
            }

            /*
            函數名稱:DivBigInt
            函數功能:二分法實現高精度整數除法
            輸入參數:const BigInt & a:用整型數組表示的高精度整數被除數
                      const BigInt & b:用整型數組表示的高精度整數除數
            輸出參數:BigInt:返回用整型數組表示的高精度整數商
            */
            BigInt DivBigInt(const BigInt & a, const BigInt & b)
            {
                BigInt high, low, mid, one, c;
                if ((a.size == 1 && a.val[0] == 0) || (b.size == 1 && b.val[0] == 0))
                {
                    c.size = 1;
                    c.val[0] = 0;
                    return c;
                }
               
                one.size = 1; //值為1的高精度整數
                one.val[0] = 1;
                high = a;  //上界
                low.size = 1; //下界
                low.val[0] = 0;
                while (ComPareBigInt(low, high) < 0)
                {
                    mid = HalfBigInt(AddBigInt(high, low)); //中間數
                    c = MulBigInt(mid, b);
                    if (ComPareBigInt(c, a) == 0)
                        return mid;
                    else if (ComPareBigInt(c, a) < 0)
                        low = AddBigInt(mid, one);
                    else
                        high = SubBigInt(mid, one);
                }     
                c = MulBigInt(low, b);
                if (ComPareBigInt(c, a) <= 0)
                    return low;
                else
                    return SubBigInt(low, one);
            }

            /*
            函數名稱:HalfBigInt
            函數功能:高精度整數求半
            輸入參數:BigInt a:用整型數組表示的高精度整數
            輸出參數:BigInt:返回用整型數組表示的高精度整數的一半
            */
            BigInt HalfBigInt(BigInt a)
            {
                BigInt c;
                c.size = a.size;
                for (int i=a.size-1; i>0; i--)
                {
                    c.val[i] = a.val[i] / 2;  
                    if (a.val[i] % 2 == 1)
                        a.val[i-1] += WIDTHMAX;
                }
                c.val[0] = a.val[0] / 2;  
                if (c.size > 0 && c.val[c.size-1] == 0)
                    c.size--;
                   
                return c;
            }


            Posted on 2008-12-15 17:41 夢想飛揚 閱讀(2103) 評論(2)  編輯 收藏 引用

            Feedback

            # re: 高精度整數運算改進版  回復  更多評論   

            2008-12-15 19:06 by 無名
            我記得高精度乘法的高效率實現是使用FFT卷積什么的,你可以改進一下

            # re: 高精度整數運算改進版  回復  更多評論   

            2008-12-25 01:22 by 本拉瘸
            用vs2008編譯運行馬上堆棧溢出.
            国产午夜精品理论片久久影视| 久久久久久精品无码人妻| jizzjizz国产精品久久| 一本色道久久88加勒比—综合| A级毛片无码久久精品免费| 亚洲国产小视频精品久久久三级 | 日日狠狠久久偷偷色综合96蜜桃 | 美女久久久久久| 久久久国产精华液| 香港aa三级久久三级| 中文字幕乱码久久午夜| 久久精品国产只有精品66 | 亚洲午夜久久久影院| 久久精品?ⅴ无码中文字幕| 久久久久人妻一区精品性色av| 久久午夜福利电影| 成人综合伊人五月婷久久| 久久久久久久久波多野高潮| 久久国产精品免费| 久久精品一区二区三区不卡| 亚洲狠狠婷婷综合久久久久| 久久国产成人午夜aⅴ影院| 99久久精品国产高清一区二区| 精品久久亚洲中文无码| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久99精品久久久久久不卡| 久久精品国产亚洲麻豆| 久久精品国产99久久无毒不卡| 久久久久久久97| 久久久久久精品免费看SSS | 久久久不卡国产精品一区二区| 久久精品九九亚洲精品天堂| 中文字幕热久久久久久久| 久久婷婷五月综合色奶水99啪| 久久综合九色综合欧美就去吻| 久久这里只有精品视频99| 日韩亚洲国产综合久久久| 欧美久久亚洲精品| 久久天天躁夜夜躁狠狠躁2022| 亚洲中文久久精品无码| 日本久久久久亚洲中字幕|