大数计算 总结

    • 万能开头
      • 大数主要思路
    • 大数加法
    • 大数减法
    • 高精度乘法
    • 高精度除以低精度
    • 大整数的因子
    • 幂运算 阶乘 阶乘和

万能开头

贴一下代码

#include 
using namespace std;

大数主要思路

1、对数据进行判断处理 swap strlen strcmp
2、进行反向存储
3、进行计算,进位 借位(一般可以不与进制数进行比较,直接进位,因 为前置零可以去除),注意最后一位的处理
进位:
阶乘:a[n]=a[n]*j;
a[n+1]+=a[n]/n;
a[n]%=n;
乘法:a[i+j]+=a[i]*a[j];
a[i+j+1]+=a[i+j]/n;
a[i+j]%=n;
借位:
a[i]+=10; a[i+1]–; c[i]=a[i]-b[i];
c[i]=(x*10+a[i])/b;
x=(x*10+a[i])%b;
4、前置零清除:while(s[s[0]]==0)–s[0];

大数加法

主要思路就是数字用字符数组反向读入,然后最好判断一下长度,把长的放在前面然后做读入。做完之后从后面依次进位,
进位的时候要注意最后一位的处理!!!
以后尽量不用字符串第一个a[0].

//交换字符串
void swap(char *p,char *q)
{
char a[20];
strcpy(a,p);
strcpy(p,q);
strcpy(q,a);
}

//用a[0]读字符数组的长度,反向读入字符数组将他变成整型方便计算
//尽量把这个写成函数
a[0] = strlen(s);
for(i=1;i<=a[0];++i)
a[i]=s[s[0]-i]-48;

//进位
while(i<=l1||i<=l2)
{
    c[i]=a[i]+b[i]+x;
    x=c[i]/10;
    c[i]%=10;
    i++;

}
c[i]=x;//很重要!!!!
while(c[i]==0)i--;//去除前置零
for(j=i;j>=1;++j)cout<

大数减法

总得来说和大数加法差不多 这里是借位 然后最重要的是首先要判断那个哪个大。同样要注意最后一位

//判断字符串
if(strlen(s1<strlen(s2)||
strlen(s1)==strlen(s2)&&strcmp(s1,s2)<0){
    swap(s1,s2);
    cout<<"-";
}

//借位
t2=min(strlen(s1),strlen(s2));
while(i<=t2){
        x=aa[i]-bb[i];
        if(x<0){aa[i]=aa[i]-bb[i]+10;

        --aa[++i];
        }
        else {aa[i]=aa[i]-bb[i];
        ++i; 
        }

    }
    while(aa[t1]==0) --t1;  
    for(i=t1;i>=1;--i)cout<

高精度乘法

最重要的就是进位思想是首先反向存入,然后就是进位处理

for(i=0;ii)
    for(j=0;jj){
        cc[i+j]+=aa[i]*bb[j];
        cc[i+j+1]+=cc[i+j]/10;
        cc[i+j]%=10;

    }
    k=la+lb;
    while(cc[k]==0)--k;

高精度除以低精度

而且其实这里不需要反向存入,直接从前面开始除就好了
但是需要反向输出
就是一个公式

for(i=0;i1-i]-48;


    for(i=la-1;i>=0;--i){
        k=k*10+aa[i];//每位依次
        cc[i]=k/b;
        k%=b;   
        //cc[i]=(x*10+aa[i])/b;
        //x=(x*10+aa[i])%b;
    }

    while(cc[la-1]==0&&la>1)--la;
    for(i=la-1;i>=0;--i) cout<cout<cout<//x

大整数的因子

是高精度除以低精度除法的一个变式,借助算因子的那个公式

for(j=2;j<=9;++j){
        t=0;
        for(i=0;iif(a[i]-48+t>=j)
            t=((a[i]-48+t)%j)*10;
            else
            t=(a[i]-48)*10;
        }
        if(t==0){cout<" ";flag=1;
        }
    }
t=t*10+c[i]-48;
t%=n;

幂运算 阶乘 阶乘和

幂运算和阶乘运算一致,先进行进位,最后处理最高位。乘一次变一次


//引入第三个数组
for(y=1;y<=n;++y)
    {
    memset(b,0,sizeof(b));
      b[0]=a[0];
        for(j=1;j<=b[0];++j)
        {
            b[j]+=a[j]*y;
            b[j+1]=b[j]/10;
            b[j]%=10; 
        }
        while(b[b[0]+1]>0)
        {
            b[b[0]+2]=b[b[0]+1]/10;
            b[b[0]+1]%=10;
            b[0]++;
        }
        for(i=1;i<=b[0];++i)a[i]=b[i];
        a[0]=b[0];


//引入余数
for(j=1;j<=n;++j){

        k=0;//记得清零
        for(i=0;i
            t=c[i]*j+k;//变这个j就行了
            c[i]=t%10;
            k=t/10;
        }
        while(k)//记录进位 
        {
            c[count++]=k%10;
            k/=10;
        }
    }
#include
using namespace std;
int a[100000010];
char c [60];
int main() {
//从1乘到n
    int i,len,n;
    scanf("%d",&n);
    a[1]=1;
    len=1;
    for(int k=2; k<=n; k++) {
        for(i=1; i<=len; i++) {
            a[i]=a[i]*k;
        }
        for(i=1; i<=len; i++) {
            if(a[i]>=10) {
                a[i+1]+=a[i]/10;
                a[i]%=10;
            }
        }
        while(a[len+1]>0) {
            len++;
            a[len+1]=a[len]/10;
            a[len]=a[len]%10;
        }
    }
    for(i=len; i>=1; i--)
        printf("%d",a[i]);

}
c[j]=c[j]*i+k;
k=c[j]/10;
c[j]%=10;
if(k>0&&j>=len)++len;

阶乘和就是运用两个阶乘相加

#include 
using namespace std;
int a[50000]={1,1};
int s[55000]={1,0};
int b[50000]={1,1};
int r[55000]={1,0};
int main(){

    int i,j,n,k,y;
    cin>>n;
    for(y=1;y<=n;++y)
    {
    memset(b,0,sizeof(b));
      b[0]=a[0];
        for(j=1;j<=b[0];++j)
        {
            b[j]+=a[j]*y;
            b[j+1]=b[j]/10;
            b[j]%=10; 
        }
        while(b[b[0]+1]>0)
        {
            b[b[0]+2]=b[b[0]+1]/10;
            b[b[0]+1]%=10;
            b[0]++;
        }
        for(i=1;i<=b[0];++i)a[i]=b[i];
        a[0]=b[0];
    memset(r,0,sizeof(r));
    r[0]= max(a[0],s[0]);   
        for(k=1;k<=r[0];++k)
        {
            r[k]+=s[k]+a[k];
            r[k+1]=r[k]/10;
            r[k]%=10;
        }
        while(r[r[0]+1]>0)
        {
            r[r[0]+2]=r[r[0]+1]/10;
            r[r[0]+1]%=10;
            r[0]++;
        }

        s[0]=r[0];

    for(i=1;i<=r[0];++i)s[i]=r[i];


        }
while(s[s[0]]==0)--s[0];
for(i=s[0];i>=1;--i)cout<return 0;   
}

你可能感兴趣的:(算法基础-高精度计算)