大数加减乘


能力有限,除法就不写了。。

关于大数

在C/C++语言编写过程中,数据并不是可以一直增长下去,数据极限大小由数据类型本身所占字节所决定,而一个字节大小为8比特,int类型占4个字节,每个类型的首位01所代表的是正负值,于是,int类型的范围为 -231 ~ 231-1,无符号类型的int(unsigned int)由于不需要表示正负,范围会大一些 0 ~ 232-1,而若是我们想表达更大的数据,就不能再使用普通的int或其他的数据类型,我们需要使用int类型的数组,将每一位数字看成字符将它一位一位存进这个数组,这样一来,从理论上看,我们就可以无限制的存储一位数字了

思路

对两个数组进行计算,所做的事就是模拟小学时的竖式计算

          562
        + 469
       ________
         1031

将每一位进位或退位储存到一个值中在进行下一位计算时,便使用这个值进行计算

大数加法

由这一步实现进位与储存

C.push_back(flag % 10);
flag /= 10;

完整

#include<bits/stdc++.h>
using namespace std;
string fir, sec;


vector<int>sum(vector<int> A, vector<int> B)
{
	vector<int> C;
	int flag = 0;  //最重要的一个变量
	for (int i = 0; i < A.size() || i < B.size(); i++) {   //A和B的长度可以不一样,所以小于他们最长的一个
		if (i < A.size()) flag += A[i];  //只有当A和B还有位的时候,才加
		if (i < B.size()) flag += B[i];
		C.push_back(flag % 10);  //由于可能进位,只存个位
		flag /= 10; //进位
	}
	if (flag) C.push_back(flag);  //若flag还有余下的,将这个值压入C中
	return C;
}

int main()
{
	vector<int> A, B, C;
	cin >> fir >> sec;
	for (int i = fir.size() - 1; i >= 0; i--) A.push_back(fir[i] - '0'); //将每一位数字先存进容器中,倒序存,方便后续压入
	for (int i = sec.size() - 1; i >= 0; i--) B.push_back(sec[i] - '0');
	C = sum(A, B);  //加了
	for (int i = C.size() - 1; i >= 0; i--) cout << C[i];  //倒序输出
	return 0;   //华丽的结束
}

大数减法

减法相较加法,不同的地方在于是借位而不是进位,而较为繁琐的地方也在于比较两数谁更大,为了简便,只对两数都是正数的情况进行讨论

比较两数大小

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

借位

C.push_back((flag + 10) % 10);
if (flag < 0) flag = 1;
else flag = 0;

完整

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
string fir, sec;

bool cmp(vector<int> &A, vector<int> &B)
{
	/*if( A.size() > B.size() ){
        return true;
    }
    else if(A.size() < B.size()){
        return false;
    }*/
    if (A.size() != B.size()) return A.size() > B.size();  //如果A和B的长度不相等,返回A是否长于B
	for (int i = A.size() - 1; i >= 0; i--) {
		if (A[i] != B[i]) return A[i] > B[i];  //如果A[i]对应的值大于或等于B[i],返回A大于B
	}
	return true;
}

vector<int> sub(vector<int> &A, vector<int> &B)
{
	vector<int> C;
	int flag = 0;  //同加法中flag的作用
	for (int i = 0; i < A.size(); i++) {
		flag = A[i] - flag;  //由于借位操作在flag上完成,所以由A[i] - flag
		if (i < B.size()) flag -= B[i];
		C.push_back((flag + 10) % 10);  //这一步免去判断flag是否小于0,直接使用flag + 10来取余,若flag大于0,无影响,若flag小于0,通过这一步实现借位操作(学长讲的即是www)
		if (flag < 0) flag = 1; //如果flag小于0,说明上一步有过借位,令flag = 1,用于A[i]减
		else flag = 0; //如果没有借位,flag = 0
	}
	 while (C.back() == 0 && C.size() > 1) C.pop_back();
	return C;
}

int main()
{
	int flag = 1;  //正负的标记
	vector<int> A, B, C;
	cin >> fir >> sec;
	for (int i = fir.size() - 1; i >= 0; i--) A.push_back(fir[i] - '0');  //同样先压入
	for (int i = sec.size() - 1; i >= 0; i--) B.push_back(sec[i] - '0');
	if (cmp(A, B)) {         //比较fir和sec的大小,如果A大,用A做被减数
		C = sub(A, B);
	}
	else {
		C = sub(B, A); flag = -1;
	}
	if (flag == -1) cout << "-";  //如果flag为-1,结果为负数
	for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
	return 0;
}

大数乘法

乘法竖式计算中,从某一位开始乘回到哪一位做加法是关键(没有用vector…因为那时不会

#include<bits/stdc++.h>
using namespace std;
#define maxn 10000
int flag, ans[maxn];

int main()
{
    int n, flag1 = 0, flag2 = 0;
    string fir, sec;
    cin >> fir >> sec;
    int lenu, lend;
    lenu = fir.length();
    lend = sec.length();  //lend是下面的数,这个数与回退有关
    for (int i = lend - 1; i >= 0; i--) {
        n = lend - i - 1;   //回退到对应位置
        for (int j = lenu - 1; j >= 0; j--) {
           ans[n] = (fir[j] - '0') * (sec[i] - '0') + ans[n];
           flag = ans[n] / 10;    //进了多少位
           ans[n] %= 10;
           n++;
           ans[n] = flag + ans[n];   //将进的位加进下一个
        }
    }
    flag = 0;   //flag作用改变,为判断前置0
    for (n + 1; n >= 0; n--) {
        if (ans[n] != 0) flag = 1;   //去掉前置0
        if (flag == 1) cout << ans[n];
    }
    if (fir == "0" || sec == "0") cout << "0";  //这时由于将前导0全部去掉,没有答案,所以单独输出
    return 0;
}

总结

思路不复杂,就是模拟竖式,但有一些小细节需要注意,比如倒序存入带来的便利和注意点,正负号判断等等,就不写了。。
第一次写文,写的不对请告诉我。。望海涵 /doge。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值