高精度运算——加减乘除(acwing)
高精度计算,一般是指2个较为大的数进行四则运算(超过了int范围,比如这个数的位数是10的6次方),这时候可以用一个较大的字符数组来存储这样的一个大数字进行运算。
高精度加法
#include
#include
using namespace std;
//C=A+B
vector add(vector& A, vector& B)
{
vector C;
int t = 0;//进位
for (int i = 0; i < A.size() || i < B.size(); i++)
{
if (i < A.size()) t += A[i];
if (i < B.size()) t += B[i];
C.push_back(t % 10);
t /= 10;
}
if (t)C.push_back(1);
return C;
}
int main()
{
string a, b;
vectorA, B;
cin >> a >> b;//a = "123456"
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - 48);//A = { 6,5,4,3,2,1}
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - 48);
auto C = add(A, B);
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
return 0;
}
高精度减法
#include
#include
using namespace std;
//判断是否有A>=B
bool cmp(vector& A, vector& B)
{
if ( A.size() != B.size()) return A.size() > B.size();//比较A,B的位数
for (int i = A.size() - 1; i >= 0; i--)
if (A[i] != B[i])
return A[i] > B[i]; //判断A,B的位数一样后,从个位往前比较
return true;相等的话也可直接返回
}
vector sub(vector &A, vector &B)
{
vectorC;
for (int i = 0, t= 0; i < A.size(); i++)
{
t = A[i] - t; //用t保存相减的答案同时储存借位
if (i < B.size()) t -= B[i]; //判断B中数位是否计算完
C.push_back((t + 10) % 10); //这里的t正负都有可能,但我们只用取它的个位数存储
if (t < 0) t = 1; //如果t小于0,说明需要借位
else t = 0; //结位为0
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); //去除前导0,例如:003
return C;
}
int main()
{
string a, b;
vector A, B;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
if (cmp(A, B)) //结果为正数
{
auto C = sub(A, B);
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
}
else //结果为负数
{
auto C = sub(B, A);
printf("-");
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
}
return 0;
}
高精度乘法
这种高精度乘法一般是用一个特别大的数来乘上一个较为小的数(不超过int范围)
#include
#include
using namespace std;
vector mul(vector &A, int b)
{
vectorC;
int t = 0;
for (int i = 0; i < A.size() || t; i++) //要么i 循环完了,要么t 不等于0(这样写可以省下一个循环)
{
if (i < A.size()) t += A[i] * b; //每一位去相乘
C.push_back(t % 10); //相乘只后只取个位
t /= 10; //存储进位
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); //去除前导0
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vectorA;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
auto C = mul(A, b);
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
return 0;
}
#include
#include
#include //reverse函数的
using namespace std;
//A/b,商事C,余数是r
vector div(vector &A, int b, int &r)
{
vectorC;
r = 0;
for (int i = A.size() - 1; i >= 0; i--)
{
r = r * 10 + A[i];//进入下一位来计算
C.push_back(r / b);//存储商的每一位
r %= b; //余数只取最少的那一个
}
reverse(C.begin(), C.end());//这里的结果是从前往后,所以需要翻转一下
while (C.size() > 1 && C.back() == 0) C.pop_back();//去除前导0
return C;
}
int main()
{
string a;
int b = 0;
cin >> a >> b;
vectorA;
for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
int r;
auto C = div(A, b, r);
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
cout << endl << r << endl;
return 0;
}
计算机是很笨的,所以要从第一位开始计算~
这里以 r 为余数,每次计算完前一位就乘上10 进入下一位继续计算,直到最后一位。
新手小白,刚刚开始学习,还望各位指出不足之处,你们的点赞收藏就是我最大的动力!