高精度运算(大数加减乘除)阶乘

大整数加法

string add(string s1,string s2)
{
    string max,min;
    if(s1.length()>s2.length())
    {
        max=s1;min=s2;
    }
    else
    {
        max=s2;min=s1;
    }
    int l1=max.length(),l2=min.length();
    for(int i=l1-1,j=l2-1;j>=0;i--,j--)
        max[i]+=min[j]-'0';
    for(int i=l1-1;i>=1;i--)
        if(max[i]>'9')
        {
            max[i]-=10;
            max[i-1]++;
        }
    if(max[0]>'9')
    {
        max[0]-=10;
        max='1'+max;
    }
    int i;
    for(i=0;i<max.size();i++)
        if(max[i]!='0')
            break;
    if(i==max.size())
        return "0";
    else
        return max.erase(0,i);
}

大整数减法

#include <iostream>
#include <cstring>
using namespace std;
string a,b;
string  substr(string a,string b )
{
    int  i,j,k,flag=1;
    string s1,s2;
    if(a.size()<b.size()||(a.size()==b.size()&&a.compare(b)<0))
    {
        //a的长度小于b的长度  或者 a的长度等于b的长度 a小于b
        s1=a;
        a=b;
        b=s1;
        flag=0;
    }
    //始 终 令 a 的 长 度 大 于 b 的长度
    while (a.length()-1>b.length()-1)  b='0'+b;          //字符短的加前导零,使他们一样长

    for (i=a.length()-1; i>=1; i--)        //减,规整  最高位单独处理
    {
        if(a[i]>=b[i])
            a[i]=a[i]-b[i]+'0';
        else
        {
            a[i]=a[i]-b[i];
            a[i]=a[i]+10+'0';
            a[i-1]=a[i-1]-1;
        }
    }
    a[0]=a[0]-b[0]+'0';                 //  a must more than b
//
//    for( i=0; i<a.length(); i++)
//        a[i]+=48;

    for(i=0; i<a.length(); i++)     // 去零 from high to low
        if(a[i]!='0')
            break;

    if(i==a.length())
    {
        a="0";
        return a;
    }

    for(j=i,k=0; j<a.length(); j++,k++)
        s2=s2+a[j];

    if(flag!=1)
    {
        s2='-'+s2;
    }
    return s2;
}
int main()
{
    while(cin>>a>>b)
    {
        cout<<substr(a,b)<<endl;
    }
    return 0;
}
void mminus(char *str1,char *str2,char *str3)  
{  
    int len1=strlen(str1),len2=strlen(str2);  
    len1--;  
    len2--;  
    int carry=0,casen=0;  
    while(len2>=0){  
        int temp=str1[len1]-str2[len2]-carry;  
        if(temp<0){  
            str3[casen++]=temp+10+'0';  
            carry=1;  
        }else{  
            str3[casen++]=temp+'0';  
            carry=0;  
        }  
        len1--;  
        len2--;  
    }     
    while(len1>=0){  
        int temp=str1[len1]-'0'-carry;  
        if(temp<0){  
            str3[casen++]=temp+10+'0';  
            carry=1;  
        }else{  
            str3[casen++]=temp+'0';  
            carry=0;  
        }  
        len1--;  
    }  
    casen--;  
    while(str3[casen]=='0'&&casen>0){  
        casen--;  
    }  
    str3[++casen]=0;  
    casen--;  
    for(int i=0;i<casen;i++,casen--){  
        char ch=str3[i];  
        str3[i]=str3[casen];  
        str3[casen]=ch;  
    }  
    return ;  
}  

大整数乘法 ##浮点数

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

int main()
{
    char s1[300],s2[300];
    int sum[700],a[300],b[300];
    while(scanf("%s%s",s1,s2)!=EOF)
    {
//        printf("%s\n%s\n",s1,s2);
        memset(sum,0,sizeof(sum));
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        int k=0;
        for(int i=strlen(s1)-1;i>=0;i--)
            a[k++]=s1[i]-'0';
        k=0;
        for(int i=strlen(s2)-1;i>=0;i--)
            b[k++]=s2[i]-'0';
        for(int i=0;i<strlen(s1);i++)
            for(int j=0;j<strlen(s2);j++)
                sum[i+j]+=a[i]*b[j];
        for(int i=0;i<strlen(s1)+strlen(s2);i++)
            if(sum[i]>=10)
            {
                sum[i+1]+=sum[i]/10;
                sum[i]%=10;
            }
        int j;
        for(j=strlen(s1)+strlen(s2);j>=0;j--)
            if(sum[j]==0)
                continue;
            else
                break;
        if(j<0)
            printf("0");
        else
            for(int i=j;i>=0;i--)
                printf("%d",sum[i]);
        printf("\n");
    }
    return 0;
}



int sum[100000],a[100000],b[100000];

string cheng(string s1,string s2)
{
    memset(sum,0,sizeof(sum));
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    int k=0;
//    cout<<s1.size()<<" "<<s2.size()<<endl;
    for(int i=s1.size()-1;i>=0;i--)
        a[k++]=s1[i]-'0';
    k=0;
    for(int i=s2.size()-1;i>=0;i--)
        b[k++]=s2[i]-'0';
    for(int i=0;i<s1.size();i++)
        for(int j=0;j<s2.size();j++)
            sum[i+j]+=a[i]*b[j];
    for(int i=0;i<s1.size()+s2.size();i++)
        if(sum[i]>=10)
        {
            sum[i+1]+=sum[i]/10;
            sum[i]%=10;
        }
    int j;
    for(j=s1.size()+s2.size();j>=0;j--)
        if(sum[j]==0)
            continue;
        else
            break;
    string s;
    int len=0;
    if(j<0)
        s="0";
    else
        for(int i=j;i>=0;i--)
            s.push_back(sum[i]+'0');
    return s;
}
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;
}

大整数除法

高精度除以高精度

#include<iostream>
#include<string>
using namespace std;
string rev(string a)
{
    string ret=a;
    int n=a.size();
    for(int i=0;i<n/2;i++)
    {
        swap(ret[i],ret[n-i-1]);//得到逆序字符串 
    }
    return ret;
}

string add(string a,string b)//大整数加法 
{
    int lena=a.size();
    int lenb=b.size();
    a=rev(a);
    b=rev(b);
    int carry=0;
    string c;
    int i;
    for(i=0;i<lena&&i<lenb;i++)
    {
        int ai=a[i]-'0';
        int bi=b[i]-'0';
        int ci=ai+bi+carry;
        c+=(ci%10)+'0';//(ci%10)+'0'整体是一个字符,即(char)((ci%10)+'0') 
        carry=ci/10;
    }
    for(;i<lena;i++)
    {
        int ai=a[i]-'0';
        int ci=ai+carry;
        c+=(ci%10)+'0';
        carry=ci/10;
    }
    for(;i<lenb;i++)
    {
        int bi=b[i]-'0';
        int ci=bi+carry;
        c+=(ci%10)+'0';
        carry=ci/10;
    }
    if(carry==1) c=c+'1';
    return rev(c);
}

string sub(string a,string b)
{
    int lena=a.size();
    int lenb=b.size();
    if(lena<lenb||(lena==lenb&&a<b)) return "";
    a=rev(a);
    b=rev(b);
    int carry=0;
    string c;
    int i;
    for(i=0;i<lena&&i<lenb;i++)
    {
        int ai=a[i]-'0';
        int bi=b[i]-'0';
        int ci=ai-bi-carry;
        if(ci<0)
        {
            ci+=10;
            carry=1;
        }
        else carry=0;
        c+=(ci%10)+'0';
    }
    for(;i<lena;i++)
    {
        int ai=a[i]-'0';
        int ci=ai-carry;
        if(ci<0)
        {
            ci+=10;
            carry=1;
        }
        else carry=0;
        c+=(ci%10)+'0';
    }

    int lenc=c.size();
    for(i=c.size()-1;i>=0;i--)
    {
        if(c[i]=='0') lenc--;
        else break;
    }
    if(lenc==0) return "";
    c=c.substr(0,lenc);
    return rev(c);
}

string divide(string a,string b)
{
    int lena=a.size();
    int lenb=b.size();

    if(lena<lenb||(lena==lenb&&a<b))  return "0";
    string bt[11];
    bt[0]="";
    bt[1]=b;
    for(int j=2;j<=10;j++)//除法的条件限制每一位的商不可能>=10 
    {
        bt[j]=add(bt[j-1],bt[1]);
    }

    int i=lenb-1;
    string c;
    string now=a.substr(0,lenb);
    if(now<b)
    {
        now+=a[++i];//除法相当于多次减法,这样表示++i程序更快 
    }

    for(;i<lena;i++)
    {
        int ci;
        int len_now=now.size();

        for(ci=1;ci<=10;ci++)
        {
            int lbn=bt[ci].size();
            if(lbn>len_now||(lbn==len_now&&bt[ci]>now)) break;//除不下去了就跳出循环 
        }
        ci--;//看有几个数能被减,因为ci时跳出循环,所以不算在内,需要减一 
        c+=ci+'0';
        now=sub(now,bt[ci]);
        if(i<lena-1)
        {
            if(now.size()==0&&a[i+1]=='0') continue;
            now+=a[i+1];
        }
    }
    return c;
}

int main()
{
    string a,b;
    cin>>a>>b;
    cout<<divide(a,b)<<endl;
}

高精度除以低精度

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int a[100],c[100];

int main()
{
    char bcs[100];
    int b,lena,lenc,x,i;
    gets(bcs);
    cin>>b;
    lena=strlen(bcs);
    for(i=0;i<=lena-1;i++) a[i+1]=bcs[i]-'0';//从高位开始处理,所以存储不同于加法减法乘法
    //for(i=1;i<=lena;i++) cout<<a[i];
    // cout<<endl;                      验证输入处理有无问题
    x=0;
    for(i=1;i<=lena;i++)      //核心代码 按位相除法
    {
        c[i]=(x*10+a[i])/b;
        x=(x*10+a[i])%b;
    }
    lenc=1;
    while(c[lenc]==0&&lenc<lena)//商不可能比被除数位数多
    lenc++;//lenc指向第一个非零数
    //cout<<lenc<<'\n';非零的超始输出位数
    for(i=lenc;i<=lena;i++)  //输出重点看起始值,需体会,从非零位输出
        cout<<c[i];
    cout<<endl;
    return 0;

}

高精度阶乘

#include <bits/stdc++.h>

using namespace std;

typedef int INT;
const INT BASE = 1000000;
const int N = 1000;
INT digits[N];

int main()
{
    int n;
    while(scanf("%d", &n) != EOF) {
        memset(digits, 0, sizeof(digits));

        digits[0] = 1;
        int len = 1;
        for(int i = 2; i <= n; i++) {
            INT carry = 0;
            for(int j = 0; j < len; j++) {
                digits[j] = digits[j] * i + carry;
                carry = digits[j] / BASE;
                digits[j] %= BASE;
            }
            if(carry)
                digits[len++] = carry;
        }
        printf("%d!\n",  n);
        printf("%d", digits[len - 1]);
        for(int i = len - 2; i >= 0; i--)
            printf("%06d", digits[i]);
        printf("\n");
    }

    return 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;
int a[4000];//要么为全局变量

const double pi=acos(-1);
const double e=exp(1.0);

void solve(){
    int n;
    while(cin>>n){
        for(int i=0;i<4000;i++){//要么迭代赋值为0,使用memset会出现奇怪的错误
            a[i]=0;
        }
        int r=0;//是否进位
        a[0]=1;//这儿也很重要
        for(int i=2;i<=n;i++){
            for(int j=0;j<4000;j++){
                a[j]=a[j]*i+r;
                r=a[j]/10;//顺序也很重要
                a[j]%=10;
            }
        }
        //斯特灵公式(求阶乘位数)
        int res=(int)(log10(2.0*pi*n)/2.0+n*log10(n/e)+1);
       // cout<<res<<endl;
        for(int i=res-1;i>=0;i--){
            cout<<a[i];
        }
        cout<<endl;
    }

}

int main()
{
    solve();
    return 0;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值