高精度减法也同加法一样,也是用于位数太大的运算,给你一个十几位的数你可能会做直接开个long long 的数据类型就解决了,但是给你一个100位的呢,1000位的呢,开long long 也不够了,所以就要用高精度了,也就是高精度算法就是处理位数很大数据。

如果你对高精度加法也不是很熟悉你可以看这个(高精度算法——高精度加法)

c/c++最大也就是unsigned long long也就才(1019+8×1018)(10^{19}+8\times 10^{18})

如果要几百位的相加减就不行了,所以就要用高精度了,但高精度是什么呢,一句话,就是处理很大的数相加减之类就比如几百位的数相加,就是很大的数。

高精度加法,其实就是竖式减法啦。

文字描述

也就是从个位起逐位相减,遇到负的情况则向上一位借1。整体思路与加法完全一致。

最终算法:

(算法不懂的请看注释)

void sub(int a[], int b[], int c[]) {
  clear(c);

  for (int i = 0; i < LEN - 1; ++i) {
    // 逐位相减
    c[i] += a[i] - b[i];
    if (c[i] < 0) {
      // 借位
      c[i + 1] -= 1;
      c[i] += 10;
    }
  }
}

试一试,输入 1 2 输出 /9999999,诶这个zhangweihao2022怎么给了我一份假的代码啊……

事实上,上面的代码只能处理减数a大于等于被减数b的情况。处理被减数比减数小,即 a<b 时的情况很简单。
要计算aba-b的值,因为有b>ab>a,可以调用以上代码中的subsub函数,写法为sub(b,a,c)sub(b,a,c)。要得到aba-b的值,在得数前加上负号即可。

算法都教了,怎能不上食用方法呢?

食用方法:

#include<iostream>
#include<string>
using namespace std;
const int N = 10090;
int a[N], b[N], c[N];
int flag = 0;
int main()
{
    string str1;
    string str2;
    cin >> str1;
    cin >> str2;
    //上面是定义
    if ((atoi(str1.c_str()) < atoi(str2.c_str()) && str1.size() == str2.size()) || str1.size() < str2.size()){
        swap(str1, str2);
        flag = 1;
    }
    for (int i = 0; i < str1.size(); i ++)
        a[str1.size()-1-i] = str1[i] - '0';
    for (int i = 0; i < str2.size(); i ++)
        b[str2.size()-i-1] = str2[i] - '0';
    //以上是输入
    int ans = max(str1.size(), str2.size());
    for (int i = 0; i < ans; i ++){
        if (a[i] < b[i]){
            a[i+1] -= 1; // 向前位借一位
            a[i] += 10;  // 后一位就得加10
        }c[i] = a[i] - b[i];  // 之后就是正常减法了
    }
    //以下是输出
    while (c[ans-1] == 0 && ans > 1)
        ans -= 1;
    if (flag == 1)//判断是否要加复负号
        cout << "-";
    for (int i = 0; i < ans; i ++)
        cout << c[ans-1-i];
    return 0;
}

0 条评论

目前还没有评论...