C++实现高精度算法

C++实现高精度加法:

对两个(大)正整数A,B相加,输出A+B结果

思想:"列竖式"

思路

①读入字符串a,b

因为C++读入数字无法自动把每一位分开,只能先以字符串形式存取再处理

②将字符数组a,b处理为整形数组A,B

这里用vector数组更有优势,可直接读出长度且无需自己初始化长度

注:倒序读入

③参照“列竖式”的思想实现每一位加法,注意进位

核心:

A,B的读取处理和进位的处理

ps:这里未讨论负数的情况,在后续补充上高精度减法后更新

附上代码:

//正整数的高精度加法
#include<iostream>
#include<vector>

using namespace std;

vector<int> A, B, C;

vector<int> add(vector<int>& A, vector<int>& B) //传入地址就避免了拷贝原数组,速度更快
{
	//为简化算法,只讨论len(A)>=len(B)的情况,这样子就不用在讨论位数上考虑太多
	if (A.size() < B.size()) return add(B, A);

	vector<int> C;
	int t=0;//t存储A,B的某位的和
	for (int i = 0; i < A.size(); i++)
	{
		t += A[i];                              //+=是因为还有前一位的进位
		if (i < B.size()) t += B[i];            //判断B[i]是否存在
		C.push_back(t % 10);                    //保留t的个位,剩余的进位
		t /= 10;                                //留进位
	}
	if (t) C.push_back(t);                      //最后总位数进一

	return C;
}

int main()
{
	string 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]);            

	return 0;
}

C++实现高精度减法:

对两个(大)正整数A,B相减,输出A-B结果

思想:"列竖式"

思路:(和高精度加法类似)

①读入字符串a,b

因为C++读入数字无法自动把每一位分开,只能先以字符串形式存取再处理

②将字符数组a,b处理为整形数组A,B

这里用vector数组更有优势,可直接读出长度且无需自己初始化长度

注:倒序读入

③参照“列竖式”的思想实现减法,注意借位(为了简化,只讨论A>B的情况,如果A<B,先输出负号再交换A,B即可)

核心:

借位:如果对于某一位t+=A[i]-B[i]<0了,那么说明要借位,借位后留下C[i]=(t+10)%10,然后给t赋值-1以实现在计算下一位“借位”,

附上代码:

//正整数的高精度减法
#include<iostream>
#include<vector>

using namespace std;

vector<int> A, B, C;

bool cmp(vector<int>& A, vector<int>& B)
{
	//A>=B,返回1   A<B,返回0

	if (A.size() > B.size()) return true;
	
	else if (A.size() == B.size())
	{
		//从高位开始一位位比
		for (int i = A.size() - 1; i >= 0; i--)
		{
			if (A[i] > B[i]) return true;
			else if (A[i] < B[i]) return false;
		}
		return true;
	}

	else return false;
}

vector<int> sub(vector<int>& A, vector<int>& B)
{
	
	vector<int>C;
	int t = 0;
	for (int i = 0; i < A.size(); i++)
	{
		t += A[i];
		if (i < B.size()) t -= B[i];            //只有B还有第i位时才减
        //对于t<0,保留(t+10)%10;对t>0,(t+10)%10=t%10 将两种情况并到一起
		C.push_back((t + 10) % 10);  
        //借位           
		if (t < 0) t = -1;
		else t =0;
	}

	//处理前导0
	while (C.size() > 1 && C.back() == 0) C.pop_back();
	
	return C;
}

int main()
{
	string 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)) //A>=B
	{
		C = sub(A, B);
	}
	else
	{
		//结果为负数
		printf("-");
		C = sub(B, A);
		
	}
	for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
	
	return 0;
}

延伸:

对于整数间的高精度加减法,实际上均可以转化为正整数间的高精度加减法:

加法情况讨论
A+-+-
B+--+
addadd(A,B)'-'add(A,B)sub(max{A,B},min{A,B})

减法情况讨论
A+-+-
B+--+
subtractsub(max{A,B},min{A,B})即-A+B(参考加法③④)add(A,B)’-‘add(A,B)

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值