高精度算法 (High Accuracy Algorithm)

简介(Introduction)

高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。



描述(Description)

  • 对于某些需要用到很大的数运算的题目,可以利用高精度算法来解决。
  • 高精度的处理是把数字以字符的形式储存在数组中,并且利用四则运算的性质来进行加减乘除运算。


代码(Code)

// 高精度加法
vector<int> add(vector<int> &A, vector<int> &B) {
   if (A.size() < B.size()) return add(B, A);  //保证函数中的数组 “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) C.push_back(t);	//最高位仍然存在进位
    return C;
}

// 高精度减法
vector<int> sub(vector<int> &A, vector<int> &B) { // 默认传入的 A 大于 B
   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(); //去掉前导 0
   return C;
}

判断A是否大于B,若大于则顺序传入,否则倒序传入

bool cmp(vector<int> &A, vector<int> &B) {
    if (A.size() != B.size()) return A.size() > B.size();
    else {
        for (int i = A.size() - 1; i >= 0; i -- ) {
            if (A[i] != B[i])
                return A[i] > B[i];
        }
    }
    return true;
}

// 高精度乘法
vector<int> mul(vector<int> &A, int b) { // 常见的高精度乘法是一个大数乘一个较小的数
   vector<int> C;
   int t = 0;  //进位
   for (int i = 0; i < A.size() || t; i ++ ) {
       //当 A没有遍历完,或 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;
}

// 高精度除法
vector<int> div(vector<int> A, int b, int &r) {  // 除法除了会返回商,还会返回一个余数 r
   vector<int> C;
   r = 0; // 余数,r 为引用传递,每次 r 更新时,主函数中的 r 也会更新

   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;
}

Tips: 读取数据时从后往前读取,输出时也从后往前进行输出

int main() {
   string a, b;
   vector<int> 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');
   // 进行的运算操作 —— 加、减、乘、除
   // 例如:auto C = add(A, B);
   for (int i = C.size() - 1; i >= 0; i -- ) printf("%d", C[i]);
   cout << endl;

   return 0;
}

posted @ 2023-06-10 12:20  FFex  阅读(124)  评论(0编辑  收藏  举报