高精度运算
一、高精度加减高精度以及高精度乘低精度。
#include <iostream>
#include <vector> //使用了vector动态数组的方法来实现。
#include <string>
using namespace std;
vector<int> add(vector<int> A, vector<int> B)
{
cout << "高精度加法运算:\n";
if (A.size() < B.size())
return add(B, A); //要保证用更长的一个数组来完成整个循环。
vector<int>C; int t=0;
for (int i = 0; i < A.size(); i++)
{
t += A[i];
if (i < B.size())
t +=B[i];
C.push_back(t % 10);
t /= 10;
}
if (t) //注意这一步if判断,在高精度减法中就不用这一步。
C.push_back(t);
while (C.size() >= 1&& C.back() == 0) //清除前置零
C.pop_back(); //和push_back配套使用。
for (int i = C.size() - 1; i >= 0; i--)
{
cout << C[i];
}
cout << endl;
return C;
}
vector<int> mul(vector<int>A, vector<int>B)
{
cout << "高精度减法运算:\n";
if (A.size() < B.size())
return mul(B, A); //保证用长的减短的。
vector<int>C; int t = 0;
for (int i = 0; i < A.size(); i++)
{
t = A[i] - t;
if (i < B.size())
t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) //这步判断是跟高精度加法不一样的地方。
t = 1;
else
t = 0;
}
while (C.size() >1 && C.back()==0) //同样是为了清除前置零。
C.pop_back();
for (int i = C.size() - 1; i >= 0; i--)
{
cout << C[i];
}
cout << endl;
return C;
}
vector<int> solve(vector<int>A, int x)
{
cout << "高精度乘低精度:\n";
vector<int>C;
int t=0;
for (int i = 0; i < A.size(); i++)
{
t+= A[i]*x ; //挨个乘。
C.push_back(t % 10);
t /= 10;
}
if (t)
C.push_back(t);
while (C.size() > 1 && C.back() == 0)
C.pop_back();
for (int i = C.size() - 1; i >=0 ; i--) //注意一下for循环的条件。
{
cout << C[i];
}
cout << endl;
return C;
}
int main()
{
vector<int>A, B;
string a, b;
cin >> a >> b;
for (int i=0;i<a.size();i++)
{
A.push_back(a[a.size()-1-i] - '0'); //for的这两种循环方式都可以,只是下边这种看着更加简洁。
}
for (int i = b.size() - 1; i >= 0; i--)
{
B.push_back(b[i] - '0');
}
add(A, B);
mul(A, B);
solve(A, 9);
system("pause");
return 0;
}
二、高精度乘高精度。
#include <iostream>
#include <string>
using namespace std;
int a[100], b[100], c[100]; //目的是为了将string类型转化为int类型存在数组中。
int main()
{
string A, B;
cin >> A >> B;
for(int i =0;i<A.size();i++) //这些转化的for语句循环条件要注意一点。
{
a[i] = A[A.size() - 1 - i] - '0';
}
for (int i = 0; i < B.size() ; i++)
{
b[i] = B[B.size() - 1 - i] - '0';
}
for (int i = 0; i < A.size() ; i++)
{
for (int j = 0; j < B.size() ; j++)
{
c[i + j] += a[i] * b[j]; //这三条语句是主要实现过程。
c[i + j + 1] += c[i + j] / 10; //贡献进位。
c[i + j] %= 10;
}
}
int h = A.size() + B.size(); //这里用一个局部变量来大致推测长度。
for (; !c[h];) //这条语句来清除前置零;
h--;
for (int i = h; i >= 0; i--)
{
cout << c[i];
}
cout << endl;
system("pause");
return 0;
}
三、高精度阶乘
#include <iostream>
#define Max 100
using namespace std;
struct BigInt
{
int len; //;len用来记录长度;
int a[Max]; //用来存储数据。
BigInt(int x = 0)
{
memset(a, 0, sizeof(a)); //用来初始化数组。
for (len = 1; x; len++)
{
a[len] = x % 10;
x /= 10;
}
}
int& operator[](int i) //重载运算符[]为了方便定义的对象使用下标法访问
{
return a[i];
}
void flatten(int n) //一个展平函数,非常好用,这样就可以不用单独处理*和+后的结果的了。
{
len = n;
for (int i = 1; i <= n; i++)
{
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
for (; !a[len];)
len--;
}
void print() //打印结果函数。
{
for (int i = len; i >= 1; i--) //这里注意一下为什么i不是>=0以为数组里面的下标是从1开始存储的。
{
cout << a[i];
}
}
};
BigInt operator+(BigInt A, BigInt B) //运算符重载
{
BigInt C;
int h = max(A.len, B.len);
for (int i = 1; i <= h; i++)
{
C[i] = A[i] + B[i];
}
C.flatten(h + 1); //+1因为加法运算进位最多为1;
return C;
}
BigInt operator* (BigInt A, int h)
{
BigInt C;
int k = A.len;
for (int i = 1; i <= k; i++)
{
C[i] = A[i] * h;
}
C.flatten(k + 11); //这里加11是为一个int类型的数据最长为10位,如果是十位可能产生一位进位,保险起见。
return C;
}
int main()
{
int m;
cin >> m;
BigInt ans(0), fac(1); //ans(0)用于加法运算,fac(1)用来挨个乘。
for (int i = 1; i <= m; i++)
{
fac = fac * i;
ans = ans + fac;
}
ans.print();
system("pause");
return 0;
}