算法与数据结构---高精度

前言

          本文章为观看以下视频所写。

视频链接:高精度算法-加法_哔哩哔哩_bilibili

一、高精度加法 

        无论整型还是浮点型或者是long long类型可计算数据都是有限位,如何来计算指定位数的数据的加减乘除呢?这就利用到了string类型。

高精度+高精度

#include <iostream>
#include <string>
using namespace std;
string s1,s2/*高精度数值*/ ;
int a[101]/*s1的进制转换*/,b[101]/*s2的进制转换*/;
int c[101]/*高精度a和高精度b之和*/;
void strtoint(string src,int des[]){
	for(int i=0;i<src.size();i++){
		des[src.size()-i]=src[i]-'0';
	}
}
int main() {
   cin>>s1>>s2;
   //1、个位对齐-反转,字符转整型 
   strtoint(s1,a);
   strtoint(s2,b);
   int la=s1.size(),lb=s2.size();
   //2、计算c数组长度,按最长数位算
   int lc=max(la,lb)+1;
   //3、对位相加得出c数组
   for(int i=1;i<=lc;i++){
   	   c[i]=a[i]+b[i]+c[i];//当前位数字再加进位的数字(注意)
   	   c[i+1]=c[i]/10;//进位 
   	   c[i]%=10;//保留个位 
   } 
   //4、去除前导0 
   while(c[lc]==0&&lc>1){
   	lc--;
   }
   //5、倒序打印 
   for(int i=lc;i>=1;i--){
   	cout<<c[i];
   }
	return 0;
}

 二、高精度减法

高精度-高精度

#include <iostream>
#include <string>
using namespace std;
string s1,s2/*高精度数值*/ ;
int a[101]/*s1的进制转换*/,b[101]/*s2的进制转换*/;
int c[101]/*高精度a和高精度b之差*/;
void strtoint(string src,int des[]){
	for(int i=0;i<src.size();i++){
		des[src.size()-i]=src[i]-'0';
	}
}
bool cmpstr(string str1,string str2){
	if(str1.size()!=str2.size())
	   return str1.size()>=str2.size();
	else
	   return str1>=str2;
} 
int main() {
   cin>>s1>>s2;
   if(!cmpstr(s1,s2)){
   	  swap(s1,s2);
   	  cout<<'-';
   }
   int la=s1.size(),lb=s2.size();
   strtoint(s1,a);
   strtoint(s2,b);
   int lc=max(la,lb);
   for(int i=1;i<=lc;i++){
   	if(a[i]>=b[i])   //注意等号的划分,a[i]=b[i]时,也可以直接相减,划分到这里,如果没加=,划分到else里面,就可能导致死循环或结果不正确,千万注意 
   	   c[i]=a[i]-b[i];
   	else{            //不够减 
   	   c[i]=10+a[i]-b[i];
   	   a[i+1]--;
	   }   
   }
   while(c[lc]==0&&lc>1)
        lc--; 
    for(int i=lc;i>=1;i--){
    	cout<<c[i];
	}
	return 0;
}

三、高精度乘法

高精度*高精度

#include <iostream>
#include <string>
using namespace std;
string s1,s2;
int a[501],b[501],c[501];
void strtoint(string s,int x[]){
	for(int i=0;i<s.size();i++){
		x[s.size()-i]=s[i]-'0';
	}
}
int main() {
	cin>>s1>>s2;
	strtoint(s1,a);
	strtoint(s2,b);
	int la=s1.size();
	int lb=s2.size();
	int lc=la+lb;
	for(int i=1;i<=la;i++){
		for(int j=1;j<=lb;j++){
		    c[i+j-1]+=a[i]*b[j];    //根据规律可推导出 
		    c[i+j]=c[i+j-1]/10+c[i+j];   //高精度加法 
		    c[i+j-1]%=10;               //高精度加法 
		}
	}
	while(c[lc]==0&&lc>1) lc--;
	for(int i=lc;i>=1;i--){
		cout<<c[i];
	}
	return 0;
}

四、高精度除法

高精度/低精度

#include <iostream>
using namespace std;
//高精度除法(高精度/低精度)
string s;
int a[501]/*高精度*/,c[501]/*结果高精度*/;
long long b;//低精度 
int tmp;//余数 
void strtoint(string s,int x[]){
	for(int i=0;i<s.size();i++){
		x[i+1]=s[i]-'0';
	}
}
int main() {
    cin>>s>>b;
    int la=s.size();
    strtoint(s,a);
    for(int i=1;i<=la;i++){
    	c[i]=(a[i]+tmp*10)/b;
    	tmp=(a[i]+tmp*10)%b;
	}
	int lc=1;
	while(c[lc]==0&&lc<la){lc++;  //使lc指向第一个不为0的数 
	}
	for(int i=lc;i<=la;i++){
		cout<<c[i];
	}
	cout<<endl<<tmp;
	return 0;
}

高精度/高精度

方法:用减法来模拟除法

 

#include <iostream>
using namespace std;
//高精度除法(高精度/高精度)
string s1,s2;
int a[101],b[101],c[101],temp[101];
int la,lb,lc,lt;
void strtoint(string s,int x[]){
	for(int i=0;i<s.size();i++){
		x[s.size()-i]=s[i]-'0';
	}
}
int move(int B[],int TEMP[],int LB,int I){
	//向右移动I位
	for(int i=1;i<=LB;i++){
		TEMP[i+I]=B[i];
	} 
	return LB+I;   //返回移动后数组的长度 
}
int cmp(int A[],int TEMP[],int LA,int LT){
	if(LA>LT){
		return 1; 
	}
	else if(LA<LT){
		return -1;
	}
	else{
		for(int i=LA;i>=1;i--){
			if(A[i]>TEMP[i]){
				return 1;
			}
			if(A[i]<TEMP[i]){
				return -1;
			}
			
		}
	}
	return 0;  //完全相等返回0 
}
void sub(int A[],int TEMP[],int LA){
	for(int i=1;i<=LA;i++){
		if(A[i]>=TEMP[i]){   //注意等于号, A[i]>=TEMP[i]的时候也可以直接减,如果没加=划分到else里面就糟糕了,可能死循环了 
			A[i]-=TEMP[i];
		}
		else{
			A[i]+=(10-TEMP[i]);
			 A[i+1]--;  
		}	
	} 
	while(A[LA]==0&&LA>1) LA--;
}
int main() {
    cin>>s1>>s2;
    la=s1.size();
    lb=s2.size();
    strtoint(s1,a);
    strtoint(s2,b);
    lc=la-lb+1;
    for(int i=lc;i>=1;i--){
    	//每次向右移动i位 
    	lt=move(b,temp,lb,i-1);
    	while(cmp(a,temp,la,lt)>=0){
    		c[i]++;
    	//高精度减法
		sub(a,temp,la);	
		}
		la--;    //减不动la--,下次循环时 la位数少一个0 ,然后再看可以减多少个temp 
		//la--不影响lc,lc已经被赋值成了la-lb+1,是个固定的数值。 
	}
	while(c[lc]==0&&lc>1){
		lc--;
	}
	for(int i=lc;i>=1;i--){
		cout<<c[i];
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值