高精度减法【c++】超详细讲解
前言
大家学过高精度加法之后,可能已经知道高精度减法的实现方法了吧
如果你还没有学过高精度加法的话,请点击这里(很详细的)—>高精度加法【C++实现】详解
最大的问题
最大的问题莫过于负数问题了。其他方法和加法一样。
负数处理
如果a<b, a - b的算式就成了这样(12 - 431= -419):
把答案倒过来是-299,这显然与我们的正确答案-113不符。如果b-a呢,就是这样子:
这时我们加一个负号,答案就是-319,与正确答案完全符合。
核心思路
所以处理负数我们分为两种情况:
1.a > b
直接计算就好了,对位相减, 做好借位就没问题。
2.a < b
这个时候是负数,所以要做 b - a ,保证结果是整数,同时用一个变量(我用的fu记录,fu==1表示结果为负)记录正负。
核心代码如下:
if(checkzf())//checkzf()为判断a是否大于b,如果大于或等于返回true,否则返回false
{
for(int i = 0; i < lena; i++)
{
if(a[i] < b[i]) //如果当前位的被减数小于减数,就要退位
{
a[i + 1]--;//比i高的以为被借走1,所以a[i+1]--
a[i] += 10;//本位+10
}
result[i] = a[i] - b[i];//当前位计算结果为被减数-减数
}
}
else
{
fu = true;//如果a<b,输出b-a,不要忘记加负号
for(int i = 0; i < lenmax; i++)//原理同a-b一样,在这里就不再赘述了。
{
if(b[i] < a[i])
{
b[i + 1] -= 1;
b[i] += 10;
}
result[i] = b[i] - a[i];
}
}
算法过程
1.倒序输入
2.判断正负,如果a<b,结果为-(b-a), 否则结果为a-b
3.输出负号
4.倒序输出结果
代码
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int a[N], b[N], result[N];
string s1, s2;
int lena, lenb, lenmax;
bool fu = false;
bool checkzf()//checkzf()为判断a是否大于b,如果大于或等于返回true,否则返回false
{
int flag = 0;//标记是否相等
if(lena > lenb) return true;//如果a的长度大于b的长度,说明a>b,返回true
if(lena < lenb) return false;//如果a的长度大于b的长度,说明a<b,返回false
if(lena == lenb)//如果长度相等,有一个a[i]>b[i], 就说明a > b, 否则说明a<b
{
for(int i = lena - 1; i >= 0; i--)
{
if(a[i] > b[i])
{
flag = 1;//标记
return true;
}
if(a[i] < b[i])
{
flag = 1;//标记
return false;
}
}
}
if(flag == 0) return true;//如果不大也不小,就是相等了。
}
int main()
{
cin >> s1 >> s2;
lena = s1.size();
lenb = s2.size();
lenmax = max(lena, lenb);
//倒序存储
for(int i = 0; i < lena; i++) a[i] = s1[lena - i - 1] - '0';
for(int i = 0; i < lenb; i++) b[i] = s2[lenb - i - 1] - '0';
if(checkzf())//checkzf()为判断a是否大于b,如果大于或等于返回true,否则返回false
{
for(int i = 0; i < lena; i++)
{
if(a[i] < b[i]) //如果当前位的被减数小于减数,就要退位
{
a[i + 1]--;//比i高的以为被借走1,所以a[i+1]--
a[i] += 10;//本位+10
}
result[i] = a[i] - b[i];//当前位计算结果为被减数-减数
}
}
else
{
fu = true;//如果a<b,输出b-a,不要忘记加负号
for(int i = 0; i < lenmax; i++)//原理同a-b一样,在这里就不再赘述了。
{
if(b[i] < a[i])
{
b[i + 1] -= 1;
b[i] += 10;
}
result[i] = b[i] - a[i];
}
}
//删除前缀多余的0
int tmp = lenmax;
while(result[tmp] == 0 && tmp > 0) tmp--;
if(fu) printf("-");//如果fu = true,输出负号
//倒序输出
for(int i = tmp; i >= 0; i--) cout << result[i];
return 0;
}
请您点赞关注加收藏,谢谢您的阅读,您的鼓励是我更新最大的动力