高精度(基础模板)

高精度加法

数据极大,以数组形式存储数据

数据以低位向高位存储(方便进位,在数组后加数据要更加便捷)

int result[100010];
int index=0;
void add(int a[],int b[],int lena,int lenb){
    int t=0;//记录是否需要进位
    for(int i=0;i<lena||i<lenb;i++){
        if(i<lena) t+=a[i];
        if(i<lenb) t+=b[i];
        result[index++]=t%10;
        t/=10;
    }
    if(t) result[index++]=t%10;
}

高精度减法

与高精度加法类似

如果A-B中A<B则将减法变为-(B-A),这就保证了所传入的A的长度一定是大有B 的,所以只需要判断lena即可

int result[1000010];
判断A,B谁更大,选择不同模式
void sub(int numa[],int numb[],int lena,int lenb){
    int t=0;//记录是否借位
    for(int i=0;i<lena;i++){
        t=numa[i]-t;
        if(i<lenb) t-=numb[i];//判断B是否还有位
        result[index++]=(t+10)%10;//2-3,t变成-1,借一位变成12-3=9落9,3-2=1,10%10抵消,为t本身
        if(t<0) t=1;//借位在,这样在进行下一次运算时,上一位即可做到减一或不变
        else t=0;
    }
    //去除前导0,123-120=003
}
//模板
#include <stdio.h>
#include <string.h>
#define N 100010
int result[N];
int count=0;
//判断是否A>=B
int check(int numa[],int numb[],int sza,int szb){
    if(sza>szb) return 1;
    else if(sza==szb){
        for(int i=sza-1;i>=0;i--){
            if(numa[i]<numb[i]) return 0;
            else if(numa[i]==numb[i]){
                continue;
            }else{
                return 1;
            }
        }
    }else{
        return 0;
    }
}
void sub(int numa[],int numb[],int sza,int szb){
    int t=0;
    for(int i=0;i<sza;i++){
        t=numa[i]-t;
        if(i<szb) t-=numb[i];
        result[count++]=(t+10)%10;
        if(t<0) t=1;
        else t=0;
    }
    //去除前导0
    while(count>=1){//如果结果为0,保留最后一位0
        if(result[--count]==0){//先减得到最高位,如果最高位是0,继续判断
            ;
        }else{
            break;//最高位不为0直接退出
        }
    }
}
int main()
{
    char a[N],b[N];
    scanf("%s",a);
    scanf("%s",b);
    int sza=strlen(a);
    int szb=strlen(b);
    int numa[N],numb[N];
    int i,j;
    for(i=sza-1,j=0;i>=0;i--,j++) numa[j]=a[i]-'0';
    for(i=szb-1,j=0;i>=0;i--,j++) numb[j]=b[i]-'0';
    if(check(numa,numb,sza,szb)){
        sub(numa,numb,sza,szb);
        for(i=count;i>=0;i--) printf("%d",result[i]);
    }else{
        printf("-");
        sub(numb,numa,szb,sza);
        for(i=count;i>=0;i--) printf("%d",result[i]);
        //去除前导0过程中每次判断都会让count先减减,退出循环时count位必定不为0
    }
    return 0;
}

高精度乘法

思路:

​ 以高精度数组每一位乘低精度数值(看成整体)区别于普通乘法运算

int result[100010];
int count=0;
void mul(int num,int b,int sz){
    int t=0;//表示进位
    for(int i=0;i<sz||t;i++){
        if(i<sz) t+=num[i]*b;//以每一位乘低精度数值
        result[count++]=t%10;//取得个位作为结果
        t/=10;//表示进位
    }
    //去除前导0
}

/*
十进制表示
1476
1*10^3+4*10^2+7*10^1+6*10^0
*/
//模板
#include<stdio.h>
#include<string.h>
int result[100010];
int count=0;
void mul(int num[],int b,int sz){
    int t=0;
    for(int i=0;i<sz||t;i++){
        if(i<sz) t+=num[i]*b;
        result[count++]=t%10;
        t/=10;
    }
    while(count>=1){
        if(result[--count]==0);
        else break;
    }
}
int main()
{
    char num[100010];
    scanf("%s",num);
    int b;
    scanf("%d",&b);
    int sz=strlen(num);
    int number[100010];
    for(int i=sz-1,j=0;i>=0;i--,j++) number[j]=num[i]-'0';
    mul(number,b,sz);
    for(int i=count;i>=0;i--) printf("%d",result[i]);
    return 0;
}

高精度乘法(大数乘大数)

#include <stdio.h>
#include <string.h>
int res[100010];
int main()
{
	char a[2010],b[2010];
	scanf("%s",a);
	scanf("%s",b);
	int sza=strlen(a),szb=strlen(b);
	int k=sza+szb;
	int numa[10010],numb[10010];
	for(int i=sza-1,j=0;i>=0;i--,j++) numa[j]=a[i]-'0';
	for(int i=szb-1,j=0;i>=0;i--,j++) numb[j]=b[i]-'0';
	for(int i=0;i<sza;i++){
		for(int j=0;j<szb;j++){
			res[i+j]+=numa[i]*numb[j];
		}
	}
	int t=0;
	for(int i=0;i<k;i++){
		t+=res[i];
		res[i]=t%10;
		t/=10;
	}
	while(k>0&&res[k]==0) k--;
	for(int i=k;i>=0;i--) printf("%d",res[i]);
	return 0; 
}

高精度除法

思路:

​ 以高位开始,先取上一位的余数,最高位的上一位余数为0,余数*10加上下一位的数字,将所得结果与除数相除作为所得结果,下一位数位变成所得结果%除数。

int result[10010];
int count=0;
int begin=0;
int div(int num[],int sz,int b)
 {
    int r=0;//r 为余数
    for(int i=sz-1;i>=0;i--)//以高位开始进行
    {
        r=r*10+num[i];
        result[count++]=r/b;//高位结果按顺序存放
        r%=b;
    }
    //去除前导0
    while(begin<count-1){//保证有一个元素
        if(num[++begin]==0);
        else break;
    }
    return r;
 }
//模板
#include <stdio.h>
#include <string.h>
int result[100010];
int count=0;
int begin=0;
int div(int num[],int sz,int b){
    int r=0;
    for(int i=sz-1;i>=0;i--){
        r=r*10+num[i];
        result[count++]=r/b;
        r%=b;
    }
    while(begin<count-1){
        if(result[++begin]==0);
        else break;
    }
    return r;
}
int main()
{
    char num[100010];
    scanf("%s",num);
    int b;
    scanf("%d",&b);
    int sz=strlen(num);
    int number[100010];
    for(int i=sz-1,j=0;i>=0;i--,j++) number[j]=num[i]-'0';
    int r=div(number,sz,b);
    for(int i=begin;i<count;i++) printf("%d",result[i]);
    printf("\n%d",r);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值