首页 > 其他分享 >高精度运算

高精度运算

时间:2022-12-26 09:12:27浏览次数:64  
标签:memset lb 运算 la int 高精度 lc

高精度运算

众所周知,c++有一种变量叫int_64……
谁还用高精度呢
好吧NOI与CSP貌似不支持int_64的样子
完结撒花

高精度运算,是指参与运算的数(加数,减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。例如,求两个20000位的数的和。这时,就要用到高精度算法了。

高精度加法

思想

将两个加数作为string型输入或存储,再将其转化为int型数组,每个数位上只记录[0,9]的数。计算时将两个数组相同数位相加并处理进位

变量名说明

sa,sb:存储两个加数的string型数组
la,lb,lc:两个加数的位数与和的位数
a,b,c:两个加数与和

具体过程

转化字符串

for(int i=0;i<la;i++){      //注意要倒序存储
	a[la-i-1]=sa[i]-'0';    //char与int间转化
}
for(int i=0;i<lb;i++){
	b[lb-i-1]=sb[i]-'0';
}

初步确定和的位数

lc=la>lb ?la: lb;       //三位运算符

各数位相加并处理进位

for(int i=0;i<lc;i++){
	c[i]+=a[i]+b[i];    
	if(c[i]>9){        //处理进位
		c[i+1]+=1;
		c[i]-=10;
	}
}

位数处理

if(c[lc]>9)	lc++;

完整代码

    #include<bits/stdc++.h>
    using namespace std;
    int la,lb,lc,a[510],b[510],c[510];
    char x[510],y[510];
    int main(){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        scanf("%s",x);
        scanf("%s",y);
        la=strlen(x);
        lb=strlen(y);
        lc=la>lb? la:lb;
        for(int i=0;i<la;i++)	a[la-i-1]=x[i]-'0';
        for(int i=0;i<lb;i++)	b[lb-i-1]=y[i]-'0';
        for(int i=0;i<lc;i++){
            c[i]+=a[i]+b[i];
            if(c[i]>=10){
                c[i+1]++;
                c[i]-=10;
            }
        }
        if(c[lc]>0)	lc++;
        for(int i=lc-1;i>=0;i--)	printf("%d",c[i]);
        return 0;
    }

典例

高精度减法

思想

与高精度加法相近,唯一不同是需要处理的不是进位,而是借位

具体过程

借位

if(c[i]<0){        //处理借位
	c[i+1]-=1;
	c[i]+=10;
}

使最高位非零

for(int i=lc-1;i>=0;i--){        //使结果最高位非零
	if(c[i]==0)	lc--;
	else	break;
}

完整代码

    #include<bits/stdc++.h>
    using namespace std;
    char sa[210],sb[210];
    int la,lb,lc,a[210],b[210],c[210];        //范围自取
    int main(){
        scanf("%s",sa);
        scanf("%s",sb);
        la=strlen(sa);
        lb=strlen(sb);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        for(int i=0;i<la;i++){        //char与int转化
            a[la-i-1]=sa[i]-'0';
        }
        for(int i=0;i<lb;i++){
            b[lb-i-1]=sb[i]-'0';
        }
        lc=la>lb ?la: lb;        //确定结果位数上限
        memset(c,0,sizeof(c));
        for(int i=0;i<lc;i++){
            c[i]=a[i]-b[i]+c[i];
            if(c[i]<0){        //处理借位
                c[i+1]-=1;
                c[i]+=10;
            }
        }
        if(c[lc]<0)	lc--;
        for(int i=lc-1;i>=0;i--){        //使结果最高位非零
            if(c[i]==0)	lc--;
            else	break;
        }
        for(int i=lc-1;i>=0;i--){
            printf("%d",c[i]);
        }
        return 0;
    }

典例

似乎没有典例……好吧可以去其他OJ上找模板题

高精度乘法

思想

与高精度加法相似其实高精度思想都差不多

具体过程

高精度乘法

    for(int i=0;i<la;i++){
            for(int j=0;j<lb;j++){
                f=x[i]*y[j];        //f:记录结果
                jw=f/10;        //jw:记录进位
                f%=10;
                w=i+j;        //精髓:w:每次数组的下标
                //这里可以参考竖式乘法,i位与j位相乘应存储在i+j位
                z[w]+=f;
                z[w+1]+=jw+z[w]/10;//处理进位
                z[w]%=10;
            }
        }

完整代码

    #include<bits/stdc++.h>
    using namespace std;
    long long la,lb,lc,x[20010],y[20010],z[20010],w,jw,f;        //注意数据大小
    char a[20010],b[20010];
    int main(){
        scanf("%s",a);
        scanf("%s",b);
        la=strlen(a);
        lb=strlen(b);
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
        memset(z,0,sizeof(z));
        for(int i=0;i<la;i++)	x[la-i-1]=a[i]-'0';
        for(int i=0;i<lb;i++)	y[lb-i-1]=b[i]-'0';
        for(int i=0;i<la;i++){
            for(int j=0;j<lb;j++){
                f=x[i]*y[j];        //f:记录结果
                jw=f/10;        //jw:记录进位
                f%=10;
                w=i+j;        //w:每次数组的下标
                z[w]+=f;
                z[w+1]+=jw+z[w]/10;//处理进位
                z[w]%=10;
            }
        }
        lc=la+lb;
        while(z[lc]==0)	lc--;
        if(lc<0)	printf("%d",0);
        else{
            for(int i=lc;i>=0;i--)	printf("%lld",z[i]);
        }
        return 0;
    }

典例

标签:memset,lb,运算,la,int,高精度,lc
From: https://www.cnblogs.com/Nebulary/p/17004955.html

相关文章

  • 高精度模板-结构体
    includeincludeincludeincludeusingnamespacestd;structBigNum{intlen,s[9999];BigNum(){memset(s,0,sizeof(s));len=1;}BigNumoperator=(co......
  • ES6三点运算符
    三点运算符,展开并合并数组   ......
  • 重载运算符
    重载运算符不会改变运算符的优先级,也无法改变运算符的运算对象数。重载某个类的某个运算符就是写一个函数定义这个类中的这个运算符。声明函数:qxzoperator+(qxzb);。......
  • C++:重载运算符
    基本概念通常我们自定义的类类型,不具有内置类型的一些操作,比如int类型的算术运算,指针类型的解引用、取地址操作,容器类型的下标操作等。因此,如果希望我们自定义的类类型......
  • 高精度学习
    高精度算法学习link:https://oi-wiki.org/math/bignum/1.输入输出#include<bits/stdc++.h>usingnamespacestd;constintLEN=1004;inta[LEN],b[LEN];v......
  • 无符号高精度
    #include<bits/stdc++.h>typedeflonglongll;constllblen=9;constllbase=1e9;constllpw[10]={1,10,100,1000,10000,100000,1000000,10000000,1......
  • Pratt Parser解释器_TDOP_自上而下的运算符优先解析
    ParttParser又称普拉特语法分析器。指沃尔-普拉特所编写的论文《TopDownOperatorPrecedence》中的基于定义优先级运算符的方式解析为AST树的一种语法分析技术。  ......
  • 2.Java基本语法(上):变量与运算符.md
    一、关键字和保留字关键字(keyword)的定义和特点定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)特点:关键字中所有字母都为小写官方地址:​​https://docs.oracle.c......
  • 模运算
    (a*b*c)%mod=((d%mod)*(c%mod))%mod(d=a*b)=((((a%mod)*(b%mod))%mod)*(c%mod))%mod在模运算下,除以一个数等于乘以这个数在模意义下的逆元......
  • 一篇文章带你了解Java中的运算符
    前言在前一篇文章中,壹哥给大家讲解了Java数据类型之间的转换,包括自动类型转换、强制类型转换、隐含的强制类型转换等问题。且在上一篇文章中,我还简单地给大家提到了Java的......