c++高精度运算 加法和乘法

c++高精度运算 加法和乘法

题目:用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50)

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n;
string midres[60];

string Mul(string str1, string str2)//乘法-解释见后面
{
    string ans="";
    int a[100] = {0}, b[100] = {0}, c[100000] = {0};
    int lena = str1.length();
    int lenb = str2.length();
    int lenc = lena + lenb;
    for (int i = 0; i < lena; i++)
    {
        a[i] = str1[lena - 1 - i] - '0';
    }
    for (int i = 0; i < lenb; i++)
    {
        b[i] = str2[lenb - 1 - i] - '0';
    }
    for (int i = 0; i < lena; i++)
        for (int j = 0; j < lenb; j++)
        {
            c[i + j] += a[i] * b[j];
            c[i + j + 1] += c[i + j] / 10;
            c[i + j] %= 10;
        }
    while (c[lenc - 1] == 0 && lenc > 1)
    {
        lenc--;
    }
    for (int i = lenc - 1; i >= 0; i--)
    {
        ans += (c[i] + '0');
    }
    return ans;
}
string add(string str1, string str2)
{
    reverse(str1.begin(), str1.end());
    reverse(str2.begin(), str2.end());
    int lena = str1.length();
    int lenb = str2.length();
    if (lena > lenb)
    {
        int temp = lena - lenb;
        while (temp--)
        {
            str2 += '0';
        }
        lenb = str2.length();
    }
    else
    {
        int temp = lenb - lena;
        while (temp--)
        {
            str1 += '0';
        }
        lena = str1.length();
    }
    int plus = 0;
    string ans = "";
    for (int i = 0; i < lena; i++)
    {
        int temp = (str1[i] - '0') + (str2[i] - '0') + plus;
        ans += temp % 10 + '0';
        plus = temp / 10;
    }

    if (plus != 0)
    {
        ans += (plus + '0');
    }
    reverse(ans.begin(), ans.end());
    return ans;
}
int main()
{
    cin >> n;
    midres[0] = "0";
    midres[1] = "1";
    midres[2] = "2";
    midres[3] = "6";
    if (n > 3)
    {
        for (int i = 4; i <= n; i++)
        {
            string s = "";
            //由于n<=50,所以n只能是个两位数
            if (i >= 10)
            {
                s = (i / 10 + '0');
                s += (i % 10 + '0');
                
            }
            else
            {
                s = (i + '0');
            }
            
            midres[i] = Mul(midres[i - 1], s);
        }
    }
    string ans = "0";
    for (int i = 0; i <= n; i++)
    {
        ans=add(ans, midres[i]);
    }
    cout<<ans;
    return 0;
}

参看乘法原理:

乘法竖式
关键点分析
1.核心代码(乘法运算部分)是由模拟乘法竖式算出来的:
(1) 数1的倒数第i位与数2的倒数第j位相乘所得到的值应存在结果的倒数第i+j位上。
(2) 如果结果的i+j位大于9,则进位到i+j+1位。

c[i+j]+=an[j]*bn[i];
c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;

i 位数 与 j 位数 相乘,其结果最多为 i+j 位。

要注意结果前缀中的0以及结果为0的情况。

while(c[cLen-1]==0 && cLen>1){
cLen--;
}

版权声明:本文为sinat_36793832原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。