高精度减法

本文详细介绍了如何使用高精度算法进行整数减法,包括输入转换、字符串处理、大小比较、借位运算和结果输出,以及去零操作,以确保正确处理超出longlong范围的大数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

高精度减法。

输入格式

两个整数 a,b(第二个可能比第一个大)。

输出格式

结果(是负数要输出负号)。

输入输出样例

输入 

2
1

输出 

1

说明/提示

  • 20% 数据 a,b 在 long long 范围内;
  • 100% 数据 0≤a,b≤10^10086。

10的10086次方肯定是超出了long long的数据范围了,所以说,这道题就要用到高精度

高精度请见高精度加法

照常输入(但还是倒序)

string sa,sb;
int a[10087],b[10087];
cin>>sa>>sb;
int la=sa.length();
int lb=sb.length();
for(int i=0;i<la;i++)
	a[la-1-i]=sa[i]-'0';
for(int i=0;i<lb;i++)
	b[lb-1-i]=sb[i]-'0';

 接着就是运算

不过这之前先得做个判断,比较哪个数更大,因为如果后面的数大于前面的数,就得输出个负数

字符串怎么输出负数呢?这其实不难

拿4和7来举个例子

4 - 7 = -3

那把他们倒过来,7-4等于多少——3

这时,我们不拿发现b大于a的情况下,只需要在b-a前面输出a个负号就行了

比较大小用一个函数来解决,从高未开始依次向下比较,只要发现哪一位的那个数就大,运行完还没找到就是相等

int f(int la,int lb){
	if(la>lb)return 0;
	if(lb>la)return 1;
	for(int i=0;i<la;i++){
		if(sa[i]>sb[i])return 0;
		if(sb[i]>sa[i])return 1;
	}
	return 2;
}

如果返回值是0,正常运算(用a-b);如果返回值是1,就用b-a,输出负号,如果相等,输出0

运算过程:

也是按照减法竖式的过程,一步一步地相减,但是提前要做个比较,如果当前位小于减数的当前位,就要向前一位借一当十

if(a[i]<b[i]){
	a[i]+=10;
	a[i+1]-=1;
}

知道了这些,代码就很简单了

不过,这个代码还有缺陷

#include<bits/stdc++.h>
using namespace std;
string sa,sb;
int a[10087],b[10087],c[10087];
int f(int la,int lb){
	if(la>lb)return 0;
	if(lb>la)return 1;
	for(int i=0;i<la;i++){
		if(sa[i]>sb[i])return 0;
		if(sb[i]>sa[i])return 1;
	}
	return 2;
}
int main(){
	cin>>sa>>sb;
	int la=sa.length();
	int lb=sb.length();
	for(int i=0;i<la;i++)
		a[la-1-i]=sa[i]-'0';
	for(int i=0;i<lb;i++)
		b[lb-1-i]=sb[i]-'0';
	int lc=max(la,lb);
	int ff=f(la,lb);
	if(ff==0){
		for(int i=0;i<lc;i++){
			if(a[i]<b[i]){
				a[i]+=10;
				a[i+1]-=1;
			}
			c[i]=a[i]-b[i];
		}
	}
	if(ff==1){
		for(int i=0;i<lc;i++){
			if(b[i]<a[i]){
				b[i]+=10;
				b[i+1]-=1;
			}
			c[i]=b[i]-a[i];
		}
		cout<<"-";
	}
	if(ff==2){
		cout<<0;
		return 0;
	}
	for(int i=lc-1;i>=0;i--)cout<<c[i];//倒序输出
	return 0;
}

比如说我们输入200和199,他会输出001,但要求是1,所以还要做一步操作,去零

while循环,直到不为零

while(1){
	if(c[lc-1]==0){
		lc--;
		continue;
	}
	break;
}

 完整代码为:

#include<bits/stdc++.h>
using namespace std;
string sa,sb;
int a[10087],b[10087],c[10087];
int f(int la,int lb){
	if(la>lb)return 0;
	if(lb>la)return 1;
	for(int i=0;i<la;i++){
		if(sa[i]>sb[i])return 0;
		if(sb[i]>sa[i])return 1;
	}
	return 2;
}
int main(){
	cin>>sa>>sb;
	int la=sa.length();
	int lb=sb.length();
	for(int i=0;i<la;i++)
		a[la-1-i]=sa[i]-'0';
	for(int i=0;i<lb;i++)
		b[lb-1-i]=sb[i]-'0';
	int lc=max(la,lb);
	int ff=f(la,lb);
	if(ff==0){
		for(int i=0;i<lc;i++){
			if(a[i]<b[i]){
				a[i]+=10;
				a[i+1]-=1;
			}
			c[i]=a[i]-b[i];
		}
	}
	if(ff==1){
		for(int i=0;i<lc;i++){
			if(b[i]<a[i]){
				b[i]+=10;
				b[i+1]-=1;
			}
			c[i]=b[i]-a[i];
		}
		cout<<"-";
	}
	if(ff==2){
		cout<<0;
		return 0;
	}
	while(1){
		if(c[lc-1]==0){
			lc--;
			continue;
		}
		break;
	}
	for(int i=lc-1;i>=0;i--)cout<<c[i];
	return 0;
}

 代码很短 希望能帮助到大家

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值