高精度核心思路:使用vector存储每一位数,倒序存储,即数组从低到高存储的是个位数。
注意减法、乘法、除法都需要去掉前导零
加法:
vector<int> add(vector<int> &A, vector<int> &B)
{
vector<int> C;
int t = 0;//t来存进位
for(int i = 0;i < A.size() || i < B.size();i ++)//从个位开始加
{
if(i < A.size()) t += A[i];// t = t + A[i] + B[i]
if(i < B.size()) t += B[i];//注意位数的问题啊!!
C.push_back(t % 10);
t /= 10;
}
if(t) C.push_back(1);//如果t最后不为零要加上一位数
return C;
}
减法:
减法特指大数减去小的数,因为如果 A - B < 0, 就计算 B - A , 输出时加上负号即可
bool cmp(vector<int> &A, vector<int> &B)
{
if(A.size() != B.size()) return A.size() > B.size();//如果位数不同,则返回位数较大的数
for(int i = A.size() - 1;i >= 0;i --)//从最高位开始比较,第一个不同的位上的数大的数大
if(A[i] != B[i]) return A[i] > B[i];
return true;
}
vector<int> sub(vector<int> &A, vector<int> &B)
{
vector<int> C;
for(int i = 0, t = 0;i < A.size();i ++)//从第一位开始减,t存的是借位
{
t = A[i] - t;
if(i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);//如果t > 0,t不变,如果t < 0, 把t加上10
if(t < 0) t = 1;//如果 t < 0, 表示往前借了一位
else t = 0;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();//减法需要去掉前导零
return C;
}
乘法:
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, int &b)
{
vector<int> C;
for(int i = 0, t = 0;i < A.size() || t;i ++) //从个位开始乘
{
if(i < A.size()) t += A[i] * b;//t存的也是进位
C.push_back(t % 10);
t /= 10;
}
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
除法:
vector<int> div(vector<int> &A, int b)
{
vector<int> C;
for(int i = A.size() - 1;i >= 0;i --)//除法是从最高位开始除的,r存的是余数
{
r = r * 10 + A[i];//每次r都是前一位的余数,因此要乘10
C.push_back(r / b);
r %= b;
}
reverse(C.begin(), C.end());//除法最后存的数是正着存的,因此需要反转一次
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
R格式这道题使用的是①高精度数乘低精度数和②高精度数加低精度数
需要注意的是 ——小数点可以直接忽略掉,只需要保存下整数的位数即可
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int n;
string d;
int dot;
vector<int> D;
void mul()//高精度加
{
int t = 0;
for(int i = 0;i < D.size();i ++ )
{
t += D[i] * 2;
D[i] = t % 10;
t /= 10;
}
if(t) D.push_back(t);
}
void add(int b)
{
int t = b;//注意只有个位上的数字需要加一
for(int i = dot;i < D.size();i ++ )
{
t += D[i];
D[i] = t % 10;
t /= 10;
}
if(t) D.push_back(t);//如果t > 0,需要增加一位
}
int main()
{
cin >> n >> d;
for(int i = d.size() - 1;i >= 0;i --)
if(d[i] != '.')
D.push_back(d[i] - '0');
reverse(d.begin(), d.end());//将浮点数反转,保存下来整数的位数
dot = d.find('.');
for(int i = 0;i < n;i ++ ) mul();
if(D[dot - 1] >= 5) add(1);//小数点后一位是dot - 1位
for(int i = D.size() - 1;i >= dot;i --) cout << D[i];
cout << endl;
return 0;
}