Source code of a big Integer Operation class (bigint)

Source: Internet
Author: User

 

This article provides an integer operation, including addition, subtraction, multiplication, power, and factorial operations.

Basic Algorithms:

The basic algorithm for big integer calculation is relatively simple, and many books have introduced it. This article has a point to note that this article uses the hichina Algorithm for computation. Why is hichina used? Because the length of a hichina int can contain 4 numbers, this reduces the storage space and greatly improves the computing speed. The reason is that two numbers need to be multiplied during multiplication, and two numbers smaller than 10 thousand must be multiplied by less than 0.1 billion, if the length of an int is the same as that of an int, using a hundred millions of hexadecimal notation will result in cross-border processing, which is troublesome and time-consuming.

The power operation uses an optimization algorithm. In fact, it converts the exponent into a binary value, and then splits the operation and adds the result.

The factorial operation basically does not use the optimization strategy and uses the traditional recursive algorithm.

Code:

//
# Include <stdio. h>
# Include <math. h>
# Include <string. h>
# Include <time. h>
# Include <stdlib. h>
Class bigint
{
PRIVATE:
Int sign;
Int NB;
Int * pdata;
Void Init (INT nnb );
Void showdata (INT m );
Public:
Bigint ();
Bigint (bigint & bnum );
Bigint (INT num );
~ Bigint ();
Void show (); // displayed on the console
Void trim (); // Normalization
Bigint & operator = (INT num );
Bigint & operator = (bigint & bnum );
Int operator = (bigint & bnum );
Int Operator! = (Bigint & bnum );
Int operator> (bigint & bnum );
Int operator <(bigint & bnum );
Int operator> = (bigint & bnum );
Int operator <= (bigint & bnum );
Bigint & operator + = (bigint & bnum );
Bigint & operator-= (bigint & bnum );
Bigint & operator * = (bigint & bnum );
Int getbit (); // obtain the number of digits
Int getsign (); // get the symbol
Void cont (); // reverse number
Int readfromstr (char * Str); // numeric string converted to bigint
Int writetostr (char * Str); // convert to string
Friend bigint operator-(bigint & bnum );
};
Bigint: bigint ()
{
Sign = 0;
NB = 1;
Pdata = new int [Nb];
Pdata [0] = 0;
}
Bigint: bigint (bigint & bnum)
{
Sign = bnum. sign;
NB = bnum. NB;
Pdata = new int [Nb];
For (INT I = 0; I <NB; I ++)
Pdata [I] = bnum. pdata [I];
}
Bigint: bigint (INT num)
{
* This = num;
}
Bigint ::~ Bigint ()
{
Delete [] pdata;
}
Void bigint: Init (INT nnb)
{
Delete [] pdata;
NB = nnb;
Pdata = new int [Nb];
For (INT I = 0; I <NB; I ++)
Pdata [I] = 0;
}
Void bigint: showdata (INT m)
{
Printf ("% C", pdata [m]/1000 + '0', (pdata [m] % 1000)/100 + '0 ', (pdata [m] % 100)/10 + '0', pdata [m] % 10 + '0 ');
}
Void bigint: Show () // displayed on the console
{
Int I;
If (Sign =-1)
Printf ("-");
For (I = nb-1; I> = 0; I --)
{
Showdata (I );
}
}
Void bigint: trim () // Normalization
{
Int I, J;
For (I = nb-1; I> 0; I --)
{
If (pdata [I]! = 0)
Break;
}
If (I = nb-1)
Return;
Bigint bnum = * this;
Init (I + 1 );
For (j = 0; j <= I; j ++)
{
Pdata [J] = bnum. pdata [J];
}
}
Bigint & bigint: Operator = (INT num)
{
Int n = ABS (Num );
If (num = 0)
Sign = 0;
Else if (Num> 0)
Sign = 1;
Else
Sign =-1;
If (n <1, 10000)
{
Init (1 );
Pdata [0] = N;
}
Else if (n <1, 100000000)
{
Init (2 );
Pdata [1] = N/10000;
Pdata [0] = n % 10000;
}
Else
{
Init (3 );
Pdata [2] = N/100000000;
Pdata [1] = (N % 100000000)/10000;
Pdata [0] = n % 10000;
}
Return * this;
}

Bigint & bigint: Operator = (bigint & bnum)
{
Int I;
If (this = & bnum)
Return * this;
Sign = bnum. sign;
NB = bnum. NB;
Init (NB );
For (I = 0; I <NB; I ++)
{
Pdata [I] = bnum. pdata [I];
}
Return * this;
}
Int bigint: Operator = (bigint & bnum)
{
If (this = & bnum)
Return 1;
If (sign! = Bnum. Sign)
Return 0;
Trim ();
Bnum. Trim ();
If (NB! = Bnum. nb)
Return 0;
For (INT I = 0; I <NB; I ++)
{
If (pdata [I]! = Bnum. pdata [I])
Return 0;
}
Return 1;
}
Int bigint: Operator! = (Bigint & bnum)
{
Return! (* This = bnum );
}
Int bigint: Operator> (bigint & bnum)
{
If (this = & bnum)
Return 0;
If (sign> bnum. Sign)
Return 1;
If (sign <bnum. Sign)
Return 0;
If (Sign = 0)
Return 0;
Trim ();
Bnum. Trim ();
If (NB> bnum. nb)
{
If (sign> 0)
Return 1;
Else
Return 0;
}
If (Nb <bnum. nb)
{
If (sign> 0)
Return 0;
Else
Return 1;
}
For (INT I = nb-1; I> = 0; I --)
{
If (pdata [I]> bnum. pdata [I])
{
If (sign> 0)
Return 1;
Else
Return 0;
}
Else if (pdata [I] <bnum. pdata [I])
{
If (sign> 0)
Return 0;
Else
Return 1;
}
}
Return 0;
}
Int bigint: Operator <(bigint & bnum)
{
Return bnum> (* This );
}
Int bigint: Operator >=( bigint & bnum)
{
Return * This = bnum | * This> bnum;
}
Int bigint: Operator <= (bigint & bnum)
{
Return * This = bnum | * THIS <bnum;
}
//////////////////////////////////////// ///////////////////////
Bigint operator + (bigint & bnum1, bigint & bnum2)
{
Bigint bnum3;
Bnum3 = bnum1;
Bnum3 + = bnum2;
Return bigint (bnum3 );
}
Bigint operator-(bigint & bnum1, bigint & bnum2)
{
Bigint bnum3;
Bnum3 = bnum1;
Bnum3-= bnum2;
Return bigint (bnum3 );
}
Bigint operator * (bigint & bnum1, bigint & bnum2)
{
Bigint bnum3;
Bnum3 = bnum1;
Bnum3 * = bnum2;
Return bigint (bnum3 );
}

//////////////////////////////////////// ////////////////////////
Bigint & bigint: Operator + = (bigint & bnum)
{
If (this = & bnum)
{
Bigint bnum1 = bnum;
* This = bnum1 + bnum1;
Return * this;
}
If (Sign = 0)
{
Return bnum;
}
If (bnum. Sign = 0)
{
Return * this;
}
Int I, m;
Bigint bnum0, * P1, * P2;
If (sign <0 & bnum. Sign <0)
{
This-> Sign = 1;
Bnum0 = bnum;
Bnum0.sign = 1;
* This + = bnum0;
This-> Sign =-1;
Return * this;
}
If (sign> 0 & bnum. Sign <0)
{
Bnum0 = bnum;
Bnum0.sign = 1;
* This-= bnum0;
Return * this;
}
If (sign <0 & bnum. Sign> 0)
{
This-> Sign = 1;
Bnum0 = bnum;
Bnum0.sign = 1;
* This-= bnum0;
This-> Sign =-1;
Return * this;
}
Bnum0 = * this;
If (bnum. NB> bnum0.nb)
{
M = bnum. NB;
P1 = & bnum;
P2 = & bnum0;
}
Else
{
M = bnum0.nb;
P1 = & bnum0;
P2 = & bnum;
}
If (P1-> NB = P2-> NB & (P1-> pdata [M-1] + P2-> pdata [M-1])> = 9999)
Init (m + 1 );
Else if (P1-> pdata [M-1]> = 9999)
Init (m + 1 );
Else
Init (m );
Sign = 1;
For (I = 0; I <P2-> NB; I ++)
{
Pdata [I] = p1-> pdata [I] + P2-> pdata [I];
}
For (; I <P1-> NB; I ++)
Pdata [I] = p1-> pdata [I];
For (I = 0; I <NB; I ++)
{
If (pdata [I] >=10000)
{
// Pdata [I + 1] = pdata [I + 1] + pdata [I]/10000;
Pdata [I + 1] + = 1;
Pdata [I] = pdata [I] %10000;
}
}
Return * this;
}
Bigint & bigint: Operator-= (bigint & bnum)
{
If (this = & bnum | * This = bnum)
{
* This = 0;
Return * this;
}
Int I, m;
Bigint bnum0, * P1, * P2;
If (sign <0 & bnum. Sign <0)
{
This-> Sign = 1;
Bnum0 = bnum;
Bnum0.sign = 1;
* This = bnum0-* this;
Return * this;
}
If (sign> 0 & bnum. Sign <0)
{
Bnum0 = bnum;
Bnum0.sign = 1;
* This + = bnum0;
Return * this;
}
If (sign <0 & bnum. Sign> 0)
{
This-> Sign = 1;
* This + = bnum;
This-> Sign =-1;
Return * this;
}
Bnum0 = * this;
If (bnum0> bnum)
{
M = bnum0.nb;
P1 = & bnum0;
P2 = & bnum;
Init (m );
Sign = 1;
}
Else
{

M = bnum. NB;
P1 = & bnum;
P2 = & bnum0;
Init (m );
Sign =-1;
}

For (I = 0; I <P2-> NB; I ++)
{
Pdata [I] = p1-> pdata [I]-P2-> pdata [I];
}
For (; I <P1-> NB; I ++)
Pdata [I] = p1-> pdata [I];
For (I = 0; I <NB; I ++)
{
If (pdata [I] <0)
{
Pdata [I] + = 10000;
Pdata [I + 1]-= 1;
}
}
Return * this;
}
Bigint & bigint: Operator * = (bigint & bnum)
{
If (this = & bnum)
{
Bigint bnum1 = bnum;
* This = bnum1 * bnum1;
Return * this;
}
If (Sign = 0 | bnum. Sign = 0)
{
* This = 0;
Return * this;
}
Int I, j, D = 0, * temp;
Bigint bnum0;
Bnum0 = * this;
Temp = new int [bnum0.nb + 1];
Init (bnum0.nb + bnum. nb );
Sign = bnum0.sign * bnum. sign;
For (I = 0; I <bnum. NB; I ++)
{
Temp [bnum0.nb] = 0;
For (j = 0; j <bnum0.nb; j ++)
{
Temp [J] = bnum0.pdata [J] * bnum. pdata [I];
}
For (j = 0; j <bnum0.nb; j ++)
{
If (temp [J]> = 10000)
{
Temp [J + 1] = temp [J + 1] + temp [J]/10000;
Temp [J] = temp [J] % 10000;
}
}
For (j = 0; j <= bnum0.nb; j ++)
{
Pdata [J + D] + = temp [J];
}
D ++;
}
For (j = 0; j <NB; j ++)
{
If (pdata [J] >=10000)
{
Pdata [J + 1] = pdata [J + 1] + pdata [J]/10000;
Pdata [J] = pdata [J] % 10000;
}
}
Delete [] temp;
Return * this;
}
Int bigint: getbit () // obtain the number of digits
{
Int B;
Trim ();
B = (nb-1) * 4;
If (pdata [nb-1]> = 1000)
B + = 4;
Else if (pdata [nb-1]> = 100)
B + = 3;
Else if (pdata [nb-1]> = 10)
B + = 2;
Else
B + = 1;
Return B;
}
Int bigint: getsign () // get the symbol
{
Return sign;
}
Int bigint: readfromstr (char * Str) // convert the numeric string to bigint
{
Int I, j, Len = strlen (STR), SG = 0, T;
If (STR [0] = '-')
{
SG =-1;
}
Else if (STR [0] = '+ ')
{
SG = 1;
}
For (I = ABS (SG); I <Len; I ++)
{
If (STR [I] <'0' | STR [I]> '9 ')
Return 0;
}
J = ABS (SG );
While (j <Len)
{
If (STR [J]! = '0 ')
Break;
J ++;
}
If (LEN = J)
{
Init (1 );
Return 1;
}
If (LEN-j) % 4 = 0)
{
Init (LEN-j)/4 );
For (I = 0; I <NB; I ++)
{
T = 4 * I + 1;
Pdata [I] = (STR [Len-T]-'0') + (STR [len-t-1]-'0 ') * 10 + (STR [len-t-2]-'0') * 100 + (STR [len-t-3]-'0') * 1000;
}
}
Else
{
Init (LEN-j)/4 + 1 );
For (I = 0; I <nb-1; I ++)
{
T = 4 * I + 1;
Pdata [I] = (STR [Len-T]-'0') + (STR [len-t-1]-'0 ') * 10 + (STR [len-t-2]-'0') * 100 + (STR [len-t-3]-'0') * 1000;
}
I = ABS (SG );
If (LEN-j) % 4 = 1)
Pdata [nb-1] = STR [I + 0]-'0 ';
Else if (LEN-j) % 4 = 2)
Pdata [nb-1] = (STR [I + 0]-'0') * 10 + (STR [I + 1]-'0 ');
Else
Pdata [nb-1] = (STR [I + 0]-'0') * 100 + (STR [I + 1]-'0 ') * 10 + STR [I + 2]-'0 ';
}
If (SG <0)
Sign =-1;
Else
Sign = 1;
Return NB;
}
Int bigint: writetostr (char * Str) // convert to string
{
Int I, Len, K;
Trim ();
K = pdata [nb-1];
If (sign <0)
K * =-1;
ITOA (K, STR, 10 );
Len = strlen (STR );
For (I = nb-2; I> = 0; I --)
{
K = nb-2-i;
STR [Len + 4 * I] = pdata [k]/1000 + '0 ';
STR [Len + 4 * I + 1] = (pdata [k] % 1000)/100 + '0 ';
STR [Len + 4 * I + 2] = (pdata [k] % 100)/10 + '0 ';
STR [Len + 4 * I + 3] = pdata [k] % 10 + '0 ';
}
Len = getbit ();
If (sign <0)
Len ++;
STR [Len] = '/0 ';
Return Len;
}
Void bigint: cont () // reverse number
{
Sign * =-1;
}
Bigint operator-(bigint & bnum)
{
Bigint bnum0;
Bnum0 = bnum;
Bnum0.sign * =-1;
Return bigint (bnum0 );
}
//////////////////////////////////////// /////////////////////////
//////////////////////////////////////// /////////////////////////
//////////////////////////////////////// /////////////////////////
//////////////////////////////////////// /////////////////////////
Bigint bfac (INT m) // factorial
{
Bigint N1, N2;
N2 = 1;
For (INT I = 2; I <= m; I ++)
{
N1 = I;
N2 * = N1;
N2.trim ();
}
Return bigint (N2 );
}

//////////////////////////////////////// ////////////////////////
Int POW (int x, int N) // The Npower of X
{
If (n = 0)
Return 1;
If (n <0)
Return 0;
Int K = N, t, s;
T = X;
S = 1;
While (1)
{
If (K % 2 = 1)
{
S * = T;
}
K = k> 1;
If (k = 0)
Break;
T = T * t;
}
Return S;
}
Bigint bpow (bigint & X, int N) // The Npower of X
{
If (n = 0)
Return 1;
If (n <0)
Return 0;
Int K = N;
Bigint t, s;
T = X;
S = 1;
While (1)
{
If (K % 2 = 1)
{
S * = T;
}
K = k> 1;
If (k = 0)
Break;
T = T * t;
}
Return bigint (s );
}
Bigint bpow (int x, int N) // The Npower of X
{
Bigint C;
If (n = 1)
{
C = X;
Return bigint (C );
}
If (n = 2)
{
C = x * X;
Return bigint (C );
}
If (n = 3)
{
C = x * X;
Return bigint (C );
}
Double n1 = Log (2147483647), n2 = Log (X );
Int M = (INT) (log (2147483647)/log (x ));
If (M> = N)
{
C = (INT) Pow (x, N );
Return bigint (C );
}
Int DIV = N/m, MOD = n % m;
Bigint S;
C = (INT) Pow (x, M );
S = bpow (C, Div );
C = (INT) Pow (x, MoD );
S * = C;
Return bigint (s );
}
//////////////////////////////////////// ////////////////////////
Int main ()
{
Int I, j, S;
Clock_t t_begin, t_end;
Bigint A, B, C, D, E;
A = 954654411;
B = 1921412412;
C = 1921412412;
C. readfromstr ("4353452543532542542542123456789"); C. Show (); printf ("/N ");
Char STR [200];
B. writetostr (STR );
Printf ("% s/n", STR );
D = C-;
// D = d + C;
D. Show ();
Printf ("/n % d/N", D. getbit ());
// Printf ("/N ");
C = a + B + B;

T_begin = clock ();
For (I = 0; I <10000; I ++)
C + = B;
T_end = clock ();
Printf ("Code Time: %. 3f seconds/N", (double) (t_end-t_begin)/clocks_per_sec );

C. Show ();
Printf ("/N ");
T_begin = clock ();
E = bfac (1, 1000 );
T_end = clock ();
Printf ("% d/N", E. getbit ());
Printf ("Code Time: %. 3f seconds/N", (double) (t_end-t_begin)/clocks_per_sec );
E. Trim ();
E. Show ();
Printf ("/N ");
Return 0;
}

 

The division operation is not provided in this article because no efficient algorithm is found. The basic idea is to first approximate a large integer to a double or long double type. After division, the product of the divisor minus the multiplier and the approximate quotient (integer) to obtain a new big integer. Use this big integer to perform cyclic operations according to the preceding steps, until we get a new big integer that is less than the divisor (I .e. the remainder), the quotient is the sum of the approximate operators.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.