高精度运算 加 减 乘 除

**由于int只能存109,longlong只能存1018,在有些时候不够用了我们就会用这种方法进行高精度运算。 思想:开一个数组,用数组存各个位数,最后按顺序输出。

A+B

797E521C556D5B5788E23A4326917CD5.jpg

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
//高精度加法 
char s1[505],s2[505];		//1.全局变量容量更大,因为是放到堆里的 
int a[505],b[505],c[505];	//2.全局变量自动赋0了,因为放到了0页里 

int main() {
	int la,lb,lc;
	scanf("%s",s1);			//输入两个字符串 
	scanf("%s",s2);	
	 
	la = strlen(s1);		//记录两个数字的长度,后面比较用 
	lb = strlen(s2);
 	
 	for(int i = 0;i < la;i++)	//倒装两个数 
		a[la-i] = s1[i] - '0';
	for(int i = 0;i < lb;i++)
		b[lb-i] = s2[i] - '0';
		
	lc = max(la,lb) + 1; 	//防止进位,多给他一位
	
	for(int i = 1;i <= lc;i++){	//核心算法!!!! 
		c[i] = c[i] + a[i] + b[i];
		c[i+1] = c[i]/10;
		c[i] = c[i]%10;
	} 
	 
	if(c[lc]==0 && lc>0) lc--;//删掉前0
	
	for(int i = lc;i >= 1;i--)	//逆序输出 
		printf("%d",c[i]);
		
	return 0;
}

A-B

B427309675F4084CD9E4053034462C1E.jpg
2B1D89177DD596B9FDE688F2471C60A1.jpg

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

char s1[505],s2[505],s3[505];
int a[505],b[505],c[505];
int p;

bool cmp(char s1[],char s2[]){
	int a = strlen(s1),b = strlen(s2);//先比较两个数的长度 
	if(a != b) return a > b;	// 如果两个数不一边长的话,返回比较的值。
	
	for(int i = 0;i < a;i++){	
		if(s1[i] != s2[i]) return s1[i] > s2[i];	//如果位数相等,需要逐位比较 
	}
	
	return true;				//两个数一样大,就是真 
}

int main(){
	
	int la,lb,lc;
	scanf("%s",s1);//输入两个数 
	scanf("%s",s2);
	
	if(cmp(s1,s2) != 1){	//经过上面的函数判断得到 被减数比减数小 需要调换位置才能得到正数 
		p = 1;				//做一个标记 会在后面用到 作用是判断是否需要加上符号 
		strcpy(s3,s1);		//简单的交换函数 
		strcpy(s1,s2);
		strcpy(s2,s3);
	}
	
	la = strlen(s1);			//得到长度,进行倒装。(减法,加法,乘法一般都需要倒装) 
	lb = strlen(s2);
	for(int i = 0;i < la;i++)
		a[la-i] = s1[i] - '0';
	for(int i = 0;i < lb;i++)
		b[lb-i] = s2[i] - '0';
	
	lc = max(la,lb);			//差的长度 因为是减法 差的长度一定 <= 最长的长度 
	
	for(int i = 0;i<=lc;i++){	//核心算法   
		if(a[i] < b[i]){		//如果被减数的本位小于减数的本位,需要借位。 
			a[i+1]--;
			a[i] += 10;
		}
		c[i] = a[i] - b[i];		//如果不需要借位,就会直接计算。 
	}
	
	while(c[lc] == 0 && lc > 1) lc--;	//去零,比如1001-1000=0001;但是我们不能输出0001
										//所以我们做一个循环,去掉前面的0
										//但是也不可以都去掉,如果两个数相等,就需要保留一位0 
	if(p == 1) printf("-");				//对应前面的p,如果是负数就会输出一个负号 
	for(int i = lc;i>=1;i--)			//逆序输出 
		printf("%d",c[i]);
	
	return 0;
}

A*B

F6D5955FA045F936F6BCFC5AC8F6909A.jpg

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

char s1[505],s2[505];
int a[505],b[505],c[505];

//乘法和加法很像,因为乘法就是从加法推过来的,感谢数学家。 
int main(){
	
	int la,lb,lc; 		//输入两个数 
	scanf("%s",s1);
	scanf("%s",s2);
	
	la = strlen(s1);
	lb = strlen(s2);
	for(int i = 0;i < la;i++)	//倒装 
		a[la - i] = s1[i] - '0';
	for(int i = 0;i < lb;i++)
		b[lb - i] = s2[i] - '0';
		
	lc = la + lb;	//结果最长不会超过两个数长度相加 
	
	for(int i = 1;i <= la;i++)			//核心算法  类似二维数组 
		for(int j = 1;j<=lb;j++){
			c[i+j-1] = c[i+j-1] + a[i]*b[j];
			c[i+j] = c[i+j] + c[i+j-1]/10;
			c[i+j-1] = c[i+j-1]%10;
		}
	
	while (c[lc] == 0 && lc > 1)  lc--;	
	
	for(int i = lc;i >= 1;i--)		//输出 
		printf("%d",c[i]);
		
	return 0;
}

A/B(高精度除以低精度)

F6B81588535EA39D34C5A0C94E294806.jpg

#include<iostream>
#include<cstring>
using namespace std;

char s1[505];
long long b,c[505],x,a[505],la,lc;

int main(){
	
	cin >> s1 >> b;	//读入被除数,除数
	
	la = strlen(s1); //结果不可能超过被除数
	for(int i = 0;i <= la;i++) a[i] = s1[i-1] - '0';	//去零 除法不用倒装
	
	for(int i = 0;i <= la;i++){
		c[i] = (x * 10 + a[i] / b);
		x = (x * 10 + a[i] % b);
	} 
	
	lc = 1;
	while(c[lc] == 0 && lc < la) lc++;	//删除前0
	
	for(int i = lc;i <= la;i++) cout << c[i];	//输出
	 
	return 0;
} 

A/B(高精度除以高精度)

8E083081878882996FF9B2FC4D650F03.jpg

#include<iostream>
#include<cstring>
using namespace std;

char s1[505],s2[505];
int a[305],b[305],c[305],tmp[305];//a是被除数,b是除数,c是商 

void init(int *x){
	char s[505];
	cin >> s;
	x[0] = strlen(s);
	for(int i = 0;i<x[0];i++)
		x[x[0]-i] = s[i] - '0';
}

void print(int a[]){
	if(a[0] == 0){
		cout << 0;
		return;
	}
	for(int i = a[0];i>0;i--) cout << a[i];
	return;
}

int compare(int a[],int b[]){
	if(a[0] > b[0]) return 1;
	if(a[0] < b[0]) return -1;
	
	for(int i = a[0];i>0;i--){
		if(a[i] > b[i]) return 1;
		if(a[i] < b[i]) return -1;
	}
	return 0;
}

void minu(int a[],int b[]){
	for(int i = 1;i <= a[0];i++){
		if(a[i] < b[i]){
			a[i+1]--;
			a[i] = a[i] +10;
		}
		a[i] = a[i] -b[i];
	}
	while(a[a[0]] == 0 && a[0] > 0) a[0]--;
}

void numcpy(int p[],int q[],int n){
	for (int i = 1;i <= p[0];i++){
	q[i+n-1] = p[i];
	q[0] = p[0] + n - 1;
}
}

int main(){
	init(a);
	init(b);
	c[0] = a[0] - b[0] + 1;
	for(int i = c[0];i >= 1;i--){
		memset(tmp,0,sizeof(tmp));
		numcpy(b,tmp,i);
		while(compare(a,tmp) >= 0){
			c[i]++;
			minu(a,tmp);
		}
	}
	while(c[c[0]] == 0 && c[0] > 0) c[0]--;
	print(c);
	cout <<endl;
	print(a);
	
	 
	return 0;
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值