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版权协议,转载请附上原文出处链接和本声明。