大数四则运算模板

来自:http://blog.csdn.net/u012860063/article/details/36903491


两个大数相加:

#include <cstdio>  
#include <cmath>  
#include <cstring>  
void fan(char s[])  
{  
    char t;  
    int i,j;  
    for(i = 0,j = strlen(s)-1; i <= j; i++,j--)  
    {  
        t=s[i];  
        s[i]=s[j];  
        s[j]=t;  
    }  
}  
int main()  
{  
    int p = 0, g = 0,h = 1;  
    int k, l;  
    char x[100010], y[100010], z[100010];  
    while(scanf("%s%s",x,y)!=EOF)  
    {  
        p = 0;  
        fan(x);  
        fan(y);  
        k = strlen(x);  
        l = strlen(y);  
        int i;  
        for(i = 0; i < k || i < l; i++)  
        {  
            if(i < k && i < l )  
                z[i] = x[i]+y[i]+ p-'0';  
            else if(i < k && i >= l)  
                z[i] = x[i]+p;  
            else if(i >= k && i < l)  
                z[i] = y[i]+p;  
            if(z[i] > '9')  
            {  
                z[i]-=10;  
                p = 1;  
            }  
            else  
                p = 0;  
        }  
        if(p)  
            z[i++] = '1';  
        z[i] = '\0';  
        fan(x);  
        fan(y);  
        fan(z);  
        printf("%s + %s = %s\n",x,y,z);  
    }  
    return 0;  
} 



多个大数相加:

#include <cstdio>  
#include <cstring>  
const int MAXN = 117;  
int main()  
{  
    char s[MAXN];  
    int sum[MAXN] = {0};  
    int i, j;  
    while(gets(s))  
    {  
        int len = strlen(s);  
        if(s[0] == '0' && len == 1)  
            break;  
        for(i = 110, j = len-1; j >= 0; i--, j--)  
        {  
            sum[i] += s[j]-'0';  
        }  
    }  
    for(i = 110; i > 0; i--)  
    {  
        sum[i-1] += sum[i] / 10;  
        sum[i] %= 10;  
    }  
    for(i = 0; sum[i] == 0 && i < 111; i++)  
    {  
        if(i == 111)//意味着全为零  
        {  
            printf("0\n");  
        }  
    }  
    for( ; i < 111; i++)  
    {  
        printf("%d",sum[i]);  
    }  
    printf("\n");  
    return 0;  
}  

相乘:

#include <cstdio>  
#include <cstring>  
#include <string>  
#include <iostream>  
#include <algorithm>  
using namespace std;  
  
const int size = 1000;  //大数位数  
  
void mult(char* A,char* B,char* ans)  
{  
    int a[size+1]= {0};  
    int b[size+1]= {0};  
    int pa=0,pb=0;  
    int c[2*size+1]= {0};  
  
    int lena=strlen(A);  
    int lenb=strlen(B);  
  
    for(int i=lena-1; i>=0; i--)  
        a[pa++]=A[i]-'0';  
    for(int j=lenb-1; j>=0; j--)  
        b[pb++]=B[j]-'0';  
  
    for(pb=0; pb<lenb; pb++)  
    {  
        int w=0;  //低位到高位的进位  
        for(pa=0; pa<=lena; pa++)  
        {  
            int temp=a[pa]*b[pb]+w;  
            w=temp/10;  
            temp=(c[pa+pb]+=temp%10);  
            c[pa+pb]=temp%10;  
            w+=temp/10;  
        }  
    }  
    bool flag=false;  
    bool sign=false;  //标记ans是否为全0  
    for(pa=0,pb=lena+lenb-1; pb>=0; pb--)  
    {  
        if(!flag && c[pb]==0)  //删除ans开头的0  
            continue;  
        else  
            flag=true;  
  
        sign=true;  
        ans[pa++]=c[pb]+'0';  
    }  
    if(sign)  
        ans[pa]='\0';  
    else  
    {  
        ans[0]='0';  
        ans[1]='\0';  
    }  
  
    return;  
}  
  
int main()  
{  
    char a[size+1];  
    char b[size+1];  
    char ans[2*size+1];  
    while(cin>>a>>b)  
    {  
        mult(a,b,ans);  
        cout<<ans<<endl;  
    }  
    return 0;  
}  

相乘(string):

string sum(string s1,string s2)  //大数加法  
{  
    if(s1.length()<s2.length())  
    {  
        string temp=s1;  
        s1=s2;  
        s2=temp;  
    }  
    int i,j;  
    for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)  
    {  
        s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));   //注意细节  
        if(s1[i]-'0'>=10)  
        {  
            s1[i]=char((s1[i]-'0')%10+'0');  
            if(i) s1[i-1]++;  
            else s1='1'+s1;  
        }  
    }  
    return s1;  
}  
  
string Mult(string s,int x)  //大数乘以整形数  
{  
    reverse(s.begin(),s.end());  
    int cmp=0;  
    for(int i=0;i<s.size();i++)  
    {  
        cmp=(s[i]-'0')*x+cmp;  
        s[i]=(cmp%10+'0');  
        cmp/=10;  
    }  
    while(cmp)  
    {  
        s+=(cmp%10+'0');  
        cmp/=10;  
    }  
    reverse(s.begin(),s.end());  
    return s;  
}  
string Multfa(string x,string y)  //大数乘法  
{  
    string ans;  
    for(int i=y.size()-1,j=0;i>=0;i--,j++)  
    {  
        string tmp=Mult(x,y[i]-'0');  
        for(int k=0;k<j;k++)  
            tmp+='0';  
        ans=sum(ans,tmp);  
    }  
    return ans;  
} 


除法:

string Except(string s,int x)  //大数除以整形数  
{  
    int cmp=0,ok=0;  
    string ans="";  
    for(int i=0;i<s.size();i++)  
    {  
        cmp=(cmp*10+s[i]-'0');  
        if(cmp>=x)  
        {  
            ok=1;  
            ans+=(cmp/x+'0');  
            cmp%=x;  
        }  
        else{  
            if(ok==1)  
                ans+='0';  //注意这里  
        }  
    }  
    return ans;  
}  


浮点大数求幂:

#include <cstdio>  
#include <cstring>  
#include <iostream>  
#include <string>  
using namespace std;  
  
const int size=1000;  //大数位数  
  
void mult(char* A,char* B,char* ans)  
{  
    int i,j,k;  
  
    int fract;   //总小数个数  
    int dot=-1;  //小数点位置  
    for(k=0; A[k]!='\0'; k++)  
        if(A[k]=='.')  
            dot=k;  
    int lena=k;  
    if(dot==-1)  
        fract=0;  
    else  
        fract=lena-dot-1;  
  
    dot=-1;  
    for(k=0; B[k]!='\0'; k++)  
        if(B[k]=='.')  
            dot=k;  
    int lenb=k;  
    if(dot==-1)  
        fract+=0;  
    else  
        fract+=(lenb-dot-1);  //总小数个数  
  
    int a[size+1]= {0};  
    int b[size+1]= {0};  
    int pa=0,pb=0;  
  
    /*倒序*/  
  
    for(i=lena-1; i>=0; i--)  
    {  
        if(A[i]=='.')  
            continue;  
        a[pa++]=A[i]-'0';  
    }  
    for(j=lenb-1; j>=0; j--)  
    {  
        if(B[j]=='.')     //暂时删除小数点  
            continue;  
        b[pb++]=B[j]-'0';  
    }  
  
    int c[2*size+1]= {0};  
    int lenc;  
    for(pb=0; pb<lenb; pb++)  
    {  
        int w=0;  //低位到高位的进位  
        for(pa=0; pa<=lena; pa++) // = 为了处理最后的进位  
        {  
            int temp=a[pa]*b[pb]+w;  
            w=temp/10;  
            temp=(c[pa+pb]+=temp%10);  
            c[lenc=pa+pb]=temp%10;  
            w+=temp/10;  
        }  
    }  
  
    /*倒序,得到没有小数点的ans*/  
  
    for(pa=0,pb=lenc; pb>=0; pb--)  
        ans[pa++]=c[pb]+'0';  
    ans[pa]='\0';  
    lena=pa;  
  
    /*插入小数点*/  
  
    bool flag=true; //标记是否需要删除小数末尾的0  
    if(fract==0)   //小数位数为0,无需插入小数点  
        flag=false;  
    else if(fract<lena) //小数位数小于ans长度,在ans内部插入小数点  
    {  
        ans[lena+1]='\0';  
        for(i=0,pa=lena; pa>0; pa--,i++)  
        {  
            if(i==fract)  
            {  
                ans[pa]='.';  
                break;  
            }  
            else  
                ans[pa]=ans[pa-1];  
        }  
  
    }  
    else //小数位数大于等于ans长度,在ans前面恰当位置插入小数点  
    {  
        char temp[size+1];  
        strcpy(temp,ans);  
        ans[0]='0';  
        ans[1]='.';  
        for(int i=0; i<fract-lena; i++) //补充0  
            ans[i+2]='0';  
        for(j=i,pa=0; pa<lena; pa++)  
            ans[j++]=temp[pa];  
        ans[j]='\0';  
    }  
  
    /*删除ans小数末尾的0*/  
  
    if(flag)  
    {  
        lena=strlen(ans);  
        pa=lena-1;  
        while(ans[pa]=='0')  
            ans[pa--]='\0';  
        if(ans[pa]=='.')   //小数全为0  
            ans[pa--]='\0';  
    }  
  
    /*删除ans整数开头的0,但至少保留1个0*/  
  
    pa=0;  
    while(ans[pa]=='0')  //寻找ans开头第一个不为0的位置  
        pa++;  
  
    if(ans[pa]=='\0')  //没有小数  
    {  
        ans[0]='0';  
        ans[1]='\0';  
    }  
    else  //有小数  
    {  
        for(i=0; ans[pa]!='\0'; i++,pa++)  
            ans[i]=ans[pa];  
        ans[i]='\0';  
    }  
    return;  
}  
  
char a[size+1];  
char ans[size*size+1];  
  
int main(void)  
{  
    int b;  
    while(cin>>a>>b)  
    {  
        memset(ans,'\0',sizeof(ans));  
        ans[0]='1';  
        ans[3]='\0';  
  
        for(int i=1; i<=b; i++)  
            mult(a,ans,ans);  
  
        cout<<ans<<endl;  
    }  
    return 0;  
}  


或者下面这个 来自:http://blog.csdn.net/u012860063/article/details/39612037

/*大数加法*/   
# include<stdio.h>  
# include<string.h>  
# include<malloc.h>  
  
void add(char* a,char* b,char* c)  
{  
    int i,j,k,max,min,n,temp;  
    char *s,*pmax,*pmin;  
    max=strlen(a);  
    min=strlen(b);  
    if (max<min)  
    {  
        temp=max;  
        max=min;  
        min=temp;  
        pmax=b;  
        pmin=a;  
    }  
    else  
    {  
        pmax=a;  
        pmin=b;  
    }  
    s=(char*)malloc(sizeof(char)*(max+1));  
    s[0]='0';  
    for (i=min-1,j=max-1,k=max;i>=0;i--,j--,k--)  
        s[k]=pmin[i]-'0'+pmax[j];  
       for (;j>=0;j--,k--)  
           s[k]=pmax[j];  
    for (i=max;i>=0;i--)  
        if (s[i]>'9')  
        {  
            s[i]-=10;  
            s[i-1]++;  
        }  
    if (s[0]=='0')  
    {  
        for (i=0;i<=max;i++)  
            c[i-1]=s[i];  
           c[i-1]='\0';  
    }  
    else  
    {  
        for (i=0;i<=max;i++)  
            c[i]=s[i];  
           c[i]='\0';  
    }  
    free(s);  
}  
  
/*大数减法*/   
void subtract(char* a,char* b,char* c)  
{  
    int i,j,ca,cb;  
    ca=strlen(a);  
    cb=strlen(b);  
    if (ca>cb||(ca==cb&&strcmp(a,b)>=0))  
    {  
        for (i=ca-1,j=cb-1;j>=0;i--,j--)  
            a[i]-=(b[j]-'0');  
           for (i=ca-1;i>=0;i--)  
               if (a[i]<'0')  
               {  
                   a[i]+=10;  
                   a[i-1]--;  
            }  
        i=0;  
        while (a[i]=='0')  
            i++;  
           if (a[i]=='\0')  
          {  
              c[0]='0';  
              c[1]='\0';  
        }  
        else  
        {  
            for (j=0;a[i]!='\0';i++,j++)  
                c[j]=a[i];  
               c[j]='\0';  
        }  
    }  
    else  
    {  
        for (i=ca-1,j=cb-1;i>=0;i--,j--)  
            b[j]-=(a[i]-'0');  
           for (j=cb-1;j>=0;j--)  
               if (b[j]<'0')  
               {  
                   b[j]+=10;  
                   b[j-1]--;  
            }  
        j=0;  
        while (b[j]=='0')  
            j++;  
           i=1;  
           c[0]='-';  
           for (;b[j]!='\0';i++,j++)  
               c[i]=b[j];  
          c[i]='\0';  
    }              
}  
  
/* 大数乘法*/   
void multiply(char* a,char* b,char* c)  
{  
    int i,j,ca,cb,* s;  
    ca=strlen(a);  
    cb=strlen(b);  
    s=(int*)malloc(sizeof(int)*(ca+cb));  
    for (i=0;i<ca+cb;i++)  
        s[i]=0;  
    for (i=0;i<ca;i++)  
        for (j=0;j<cb;j++)  
            s[i+j+1]+=(a[i]-'0')*(b[j]-'0');  
    for (i=ca+cb-1;i>=0;i--)  
        if (s[i]>=10)  
        {  
            s[i-1]+=s[i]/10;  
            s[i]%=10;  
        }  
    i=0;  
    while (s[i]==0)  
        i++;  
       for (j=0;i<ca+cb;i++,j++)  
           c[j]=s[i]+'0';  
    c[j]='\0';  
    free(s);  
}  
  
/*大数除法,返回余数*/  
int dividor(char* a,int b,char* c)  
{  
    int i,j,temp=0,n;  
    char* s;  
    n=strlen(a);  
    s=(char*)malloc(sizeof(char)*(n+1));  
    for (i=0;a[i]!=0;i++)  
       {  
           temp=temp*10+a[i]-'0';  
           s[i]=temp/b+'0';  
           temp%=b;  
    }  
    s[i]='\0';  
    for (i=0;s[i]=='0'&&s[i]!='\0';i++);  
    if (s[i]=='\0')  
    {  
        c[0]='0';  
        c[1]='\0';  
    }  
    else  
    {  
        for (j=0;s[i]!='\0';i++,j++)  
            c[j]=s[i];  
           c[j]='\0';  
    }  
    free(s);  
    return temp;  
}  

补充:

这是一题大数开方、相乘的题目,我试着用上面的大数相乘模板,加上这里的开方模板,但是超时了。

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

string strMul(string a,string b)  
{  
    string result="";  
    int len1=a.length();  
    int len2=b.length();  
    int i,j;  
    int num[500]={0};  
    for(i=0;i<len1;i++)  
    for(j=0;j<len2;j++)  
    {  
        num[len1-1+len2-1-i-j]=num[len1-1+len2-1-i-j]+(a[i]-'0')*(b[j]-'0');  
    }  
    for(i=0;i<len1+len2;i++)  
    {  
        num[i+1]=num[i+1]+num[i]/10;  
        num[i]=num[i]%10;  
    }  
    for(i=len1+len2-1;i>=0;i--)  
    {  
        if(num[i]!=0)  
        break;  
    }  
    for(;i>=0;i--)  
    {  
        result=result+(char)(num[i]+'0');  
    }  
    return result;  
}  
  
int strCmp(string a,string b,int pos)  
{  
    int i;  
    if(a.length()+pos>b.length())  
    return 1;  
    if(a.length()+pos<b.length())  
    return 0;  
    if(a.length()+pos==b.length())  
    {  
        for(i=0;i<a.length();i++)  
        {  
            if(a[i]<b[i])  
            return 0;  
            if(a[i]==b[i])  
            continue;  
            if(a[i]>b[i])  
            return 1;  
        }  
          
    }  
}  
  
string strSqrt(string a)  
{  
    string result="";  
    int i;  
    int len=a.length();  
    if(len%2==0)  
    len=len/2;  
    else  
    len=len/2+1;  
    for(i=0;i<len;i++)  
    {  
        result=result+'0';  
        while(strCmp(strMul(result,result),a,2*(len-1-i))!=1)  
        {  
            if(result[i]==':')  
            break;  
            result[i]++;  
        }  
        result[i]--;  
    }  
    return result;  
}  
  
int main()  
{  
    string n,m;  
    cin>>n>>m;  
    cout<<strMul(strSqrt(n),strSqrt(m))<<endl;
    return 0;  
}  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值