大数高精度运算(模板)

前言:高精度运算。是指參与运算的数(加数。减数,因子……)范围大大超出了标准数据类型(整型,实型)能表示的范围的运算。

模板:包含大数加减乘除。大数与int数的乘法,模板能够不断扩充。

代码:

/*
所有亲測可用,可是不能用于负数的运算,仅仅能对正数进行大数运算
*/
const int ten[4]= {1,10,100,1000};
const int maxl = 300;
struct BigNumber
{
    int d[maxl];
    char s[maxl];
    BigNumber(const char s[])
    {
        int len=strlen(s);
        d[0]=(len-1)/4+1;
        int i,j,k;
        for(int i=1; i<maxl; i++)
            d[i]=0;
        for(int i=len-1; i>=0; i--)
        {
            j=(len-i-1)/4+1;
            k=(len-i-1)%4;
            d[j]+=ten[k]*(s[i]-'0');
        }
        while(d[0]>1&&d[d[0]]==0)
            d[0]--;
    }
    BigNumber()
    {
        *this=BigNumber("0");
    }
    BigNumber(int x)
    {
        for (int i=0; i<maxl; i++) d[i]=0;
        if (!x) d[0]=1;
        while(x)
        {
            d[++d[0]]=x%10000;
            x/=10000;
        }
    }
    BigNumber(long long x)
    {
        for (int i=0; i<maxl; i++) d[i]=0;
        if (!x) d[0]=1;
        while(x)
        {
            d[++d[0]]=x%10000;
            x/=10000;
        }
    }
    void print()
    {
        int len=d[0];
        printf("%d",d[d[0]]);
        for(int i=len-1; i>=1; i--)
        {
            if(d[i]>=1000)
                printf("%d",d[i]);
            else if(d[i]>=100)
                printf("0%d",d[i]);
            else if(d[i]>=10)
                printf("00%d",d[i]);
            else printf("000%d",d[i]);
        }

        printf("\n");
    }
    void toString()
    {
        int top=0;
        int i,j,temp;
        for(i=3; i>=1; i--)
            if(d[d[0]]>=ten[i])
                break;
        temp=d[d[0]];
        for(j=i; j>=0; j--)
        {
            s[top++]=(char)(temp/ten[j]+'0');
            temp%=ten[j];
        }
        for(i=d[0]-1; i>0; i--)
        {
            temp=d[i];
            for(j=3; j>=0; j--)
            {
                s[top++]=(char)(temp/ten[j]+'0');
                temp%=ten[j];
            }
        }
    }
} zero=BigNumber(),d,temp,mid1[15],a[3005];
bool operator < (const BigNumber &a,const BigNumber &b)
{
    if(a.d[0]!=b.d[0])
        return a.d[0]<b.d[0];
    int i;
    for(i=a.d[0]; i>0; i--)
        if(a.d[i]!=b.d[i])
            return a.d[i]<b.d[i];
    return false;
}
bool operator > (const BigNumber &a,const BigNumber &b)
{
    if(b.d[0]!=a.d[0])
        return b.d[0]<a.d[0];
    int i;
    for(i=b.d[0]; i>0; i--)
        if(a.d[i]!=b.d[i])
            return b.d[i]<a.d[i];
    return false;
}
bool operator ==(const BigNumber &a,const BigNumber &b)
{
    int i;
    if(a.d[0]!=b.d[0])
        return false;
    for(i=1; i<=a.d[0]; i++)
        if(a.d[i]!=b.d[i])
            return false;
    return true;
}
bool operator <= (const BigNumber &a,const BigNumber &b)
{
    return a<b||a==b;
}
bool operator >= (const BigNumber &a,const BigNumber &b)
{
    return a>b||a==b;
}
BigNumber operator +(const BigNumber &a,const BigNumber &b)
{
    BigNumber c;
    c.d[0]=max(a.d[0],b.d[0]);
    int i,x=0;
    for(i=1; i<=c.d[0]; i++)
    {
        x=a.d[i]+b.d[i]+x;
        c.d[i]=x%10000;
        x/=10000;
    }
    while(x!=0)
    {
        c.d[++c.d[0]]=x%10000;
        x/=10000;
    }
    return c;
}
BigNumber operator -(const BigNumber &a,const BigNumber &b)
{
    BigNumber c;
    c.d[0]=a.d[0];
    int i,x=0;
    for(i=1; i<=c.d[0]; i++)
    {
        x=10000+a.d[i]-b.d[i]+x;
        c.d[i]=x%10000;
        x=x/10000-1;
    }
    while((c.d[0]>1)&&(c.d[c.d[0]]==0))
        c.d[0]--;
    return c;
}
BigNumber operator *(const BigNumber &a,const BigNumber &b)
{
    BigNumber c;
    c.d[0]=a.d[0]+b.d[0];
    int i,j,x;
    for(i=1; i<=a.d[0]; i++)
    {
        x=0;
        for(int j=1; j<=b.d[0]; j++)
        {
            x=a.d[i]*b.d[j]+x+c.d[i+j-1];
            c.d[i+j-1]=x%10000;
            x/=10000;
        }
        c.d[i+b.d[0]]=x;
    }
    while((c.d[0]>1)&&(c.d[c.d[0]]==0))
        --c.d[0];
    return c;
}
bool smaller(const BigNumber &a,const BigNumber &b,int delta)
{
    if(a.d[0]+delta!=b.d[0])
        return a.d[0]+delta<b.d[0];
    int i;
    for(i=a.d[0]; i>0; i--)
        if(a.d[i]!=b.d[i+delta])
            return a.d[i]<b.d[i+delta];
    return true;
}
void Minus (BigNumber &a,const BigNumber &b,int delta)
{
    int i,x=0;
    for(i=1; i<=a.d[0]-delta; i++)
    {
        x=10000+a.d[i+delta]-b.d[i]+x;
        a.d[i+delta]=x%10000;
        x=x/10000-1;
    }
    while((a.d[0]>1)&&(a.d[a.d[0]]==0))
        a.d[0]--;
}
BigNumber operator *(const BigNumber &a,const int &k)
{
    BigNumber c;
    c.d[0]=a.d[0];
    int i,x=0;
    for(i=1; i<=a.d[0]; i++)
    {
        x=a.d[i]*k+x;
        c.d[i]=x%10000;
        x/=10000;
    }
    while(x>0)
    {
        c.d[++c.d[0]]=x%10000;
        x/=10000;
    }
    while((c.d[0]>1)&&(c.d[c.d[0]]==0))
        c.d[0]--;
    return c;
}
BigNumber operator /(const BigNumber &a,const BigNumber &b)
{
    BigNumber c;
    d=a;
    int i,j,temp;
    mid1[0]=b;
    for(int i=1; i<=13; i++)
        mid1[i]=mid1[i-1]*2;
    for(i=a.d[0]-b.d[0]; i>=0; i--)
    {
        temp=8192;
        for(j=13; j>=0; j--)
        {
            if(smaller(mid1[j],d,i))
            {
                Minus(d,mid1[j],i);
                c.d[i+1]+=temp;
            }
            temp/=2;
        }
    }
    c.d[0]=max(1,a.d[0]-b.d[0]+1);
    while((c.d[0]>1)&&(c.d[c.d[0]]==0))
        c.d[0]--;
    return c;
}
BigNumber operator %(const BigNumber &a,const BigNumber &b)
{
    BigNumber c=a/b;
    return a-b*c;
}
时间: 2024-08-28 02:39:33

大数高精度运算(模板)的相关文章

hdu4927 Series 1(组合+公式 Java大数高精度运算)

题目链接: Series 1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 423    Accepted Submission(s): 146 Problem Description Let A be an integral series {A1, A2, . . . , An}. The zero-order series o

大数运算模板

大整数加法 /* 大整数加法 调用方式:add(a, b); 返回类型:string */ string add(string a, string b) { string s; reverse(a.begin(), a.end()); reverse(b.begin(), b.end()); int i = 0; int m, k = 0; while(a[i] && b[i]) { m = a[i] - '0' + b[i] - '0' + k; k = m / 10; s += (m

大数问题(高精度运算)

一.基本概念 在某些情况下,我们必须处理相当大的一个整数,运用类型int.long int.long long int 类型均无法对其进行存储.要解决这样的问题,我们就需要自己编写相应的处理程序.在处理大数的时候,可以将其作为字符串读入,然后一个数字一个数字的存储到数组中,然后编写相应运算操作的处理函数即可解决大数问题. 也就是说在对大数进行运算之前,要先解决对大数进行存储的问题.而这里一一般情况为例,对输入和输入函数进行定义. 输入处理: 输入字符串: c[0] c[1] c[2] c[3]

高精度运算(大数)

求模(mod):直接在草稿纸上用小学方法算除法就能看出来 1 #include<stdio.h> 2 #include<string.h> 3 char m[1010]; 4 int main(){int n,temp; 5 while(~scanf("%s %d",m,&n)){temp=0; 6 for(int i=0;i<strlen(m);++i){ 7 temp=temp*10+m[i]-'0'; 8 temp%=n; 9 } 10 pr

SGU 200 Cracking RSA (高斯消元+大数高精度)

题目地址:SGU 200 这题居然还考大数高精度..无语.. 令有该因子偶数个为0,奇数个为1,这样就满足异或运算了,即奇+奇=偶,偶+偶=偶,奇+偶=奇.然后建立方程高斯消元求变元个数free_num,那么子集的个数就是2^free_num-1.减1是去掉0的情况.注意要用大数运算 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #includ

[入门]高精度运算

(本人知识 while(1)cout<<"非常"; 有限,如果你看到我有任何错漏或者不足,真的真的真的恳请大家指出,蟹蟹,我希望大家可以一起进步~) int类型的变量只能存放-2^31~2^31-1范围的数据 long long类型的变量只能存放-2^63~2^63-1范围的数据 对于大数阶乘这种肯定是存不下,因此我们需要用数组存放数据: 下面是一个高精度运算的例子: 题目描述 用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤5

高精度运算

在开发中高精度运算使用并非非常频繁,float和double的精度实际上能够满足绝大多数需要,且高精度运算效率比常规的运算要慢一点,但使用高精度运算往往是为了使用其中便捷的API.官方提供的高精度运算的类主要两个 BigInteger:当数值范围超过long时使用 BigDecimal:几乎涵盖BigInteger功能,还可以保留小数点任意位数,理论上精度无穷大,以下主要说明此类 注:两者API很相似 加减乘除 BigDecimal aaa = new BigDecimal(20); BigDe

高精度运算1

1.高精度运算_加法 AYYZOJ p1443 COGS p37 1 type 2 arr=array[1..200]of integer; 3 var 4 a,b:arr;i,la,lb:integer; n:string; 5 procedure add(a,b:arr;la,lb:integer); 6 var i,x,lc:integer; c:arr; 7 begin 8 i:=1; x:=0; 9 while (i<=la) or(i<=lb) do 10 begin x:=a[i

高精度运算专题3-乘法运算(The multiplication operation)

这个专题呢,我就来讲讲高精度的乘法,下面是三个计算乘法的函数,第一个函数是char类型的,要对字符串进行数字转换,而第二个是两个int类型的数组,不用转换成数字,第三个则更为优化,用a数组-b数组放回数组a里面 函数1思路:要先把char类型的转换成int类型的数,直接每个数-‘0’就可以实现把char类型的转换成int类型的了. ①记录数组a.数组b的长度,放到第一位 ②每个位相乘,用一个数来记录进位(初值为0),每个位相乘,加上进位,存入c数组的相对应的位置,每次进位要重新赋值 ③最后记得要