because the computer operation is a modulo operation, the representation of the data range is limited, such as int (c + + in the same int and long) expression range ( -2^31~2^31-1), unsigned long (unsigned integer) is (0~2^32-1), are about billions of. If a real type is used, the largest double can be saved to provide only a valid number of 15~16 bits, that is, only the number of trillions can be accurately expressed. Therefore, when the number of digits exceeding more than 10 bits is calculated, the existing type cannot be used and can only be programmed by itself.
High-Precision calculation general method: High-precision calculation is generally used in an array to store a number, an element of the array corresponds to the number of one (of course, in the future in order to speed up the calculation, you can also use an element of the array to represent the number of multi-digit number, temporarily do not speak), when the calculation of the number of Therefore, in order to facilitate, the number from low to high in the array subscript corresponding from low to high position, in addition, we apply for the size of the array, generally consider the largest case, in many cases, there is a surplus, that is, high there are many 0, may result in invalid operations and judgments, therefore, We typically store the number of bits in the array with the NO. 0 subscript corresponding to the position. An equivalent of 3485 (3,485), expressed in array a[10], is:
Subscript 0 1 2 3 4 5 6 7 8 9
Content 4 5 8 4 3 0 0 0 0 0
Description: Number of digits digit 10 digit hundred thousand
The method of calculating subtraction is the column vertical method used in primary school.
Note: High-precision calculations generally use positive numbers, for negative numbers, by processing the symbol bit correction.
A. Storage of high-precision numbers
1. String input, such as logarithm
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int n=100;//up to 100 bits 5 int main () 6 {7 int a[n+1],i; 8 string S1; 9 cin>>s1;//number s110 memset (a,0,sizeof (a)); Array clear 011 a[0]=s1.length (); Number of digits for (i=1;i<=a[0];i++) a[i]=s1[a[0]-i]-' 0 ';//convert characters to numbers and store them in reverse. Return 0;14}
2. Direct read-In
1 #include <iostream> 2 using namespace std; 3 const int n=100;//up to 100 bits 4 int main () 5 {6 int a[n+1],i,s,key; 7 cin>>key;//number key 8 memset (A,0,sizeof (a));//Array Clear 0 9 i=0;//No. 0 (key) //When key is greater than 011 { a[++i]=key%10;//takes the number of I bits key=key/10;14}15 a[0]=i;//Total I-digit 16 Return 0;17}
3. Direct initialization (with a[] storage)
Initialized to 0:memset (A,0,sizeof (a));
Initialized to 1:memset (A,0,sizeof (a)); a[0]=1;a[1]=1;
The following programs write only functions, do not write the complete program, all the high-precision number of storage to meet the above conventions.
Two. High precision number comparison
1 int compare (int a[],int b[]) //Compare the size relationship between A and B, if A>b is 1,a<b then -1,a=b then it is (i;3) return a[0]>b[0 A is greater than B, a greater than B 4 if (a[0]<b[0]) return-1;//a the number of bits less than B is a smaller than B 5 for (i=a[0];i>0;i--) //from high to low compared 6 {if (a[i]>b [i]) return 1;7 if (a[i]<b[i]) return-1;} 8 return 0;//Everyone equals two numbers equal. 9}
Third, high-precision addition
1 int plus (int a[],int b[])//calculate a=a+b 2 {int i,k; 3 k=a[0]>b[0]?a[0]:b[0];//k is the number of digits of the largest number of digits in A and B 4 for (i=1;i<=k;i++) 5< c2/>{a[i+1]+= (A[i]+b[i])/10; If there is carry, then advanced bit 6 a[i]= (a[i]+b[i])%10;} Calculate the current bit number, note: This statement cannot be exchanged with the previous one. 7 if (a[k+1]>0) a[0]=k+1; Fixed the number of bits of new A (a+b up to one carry) 8 else a[0]=k; 9 return 0;10}
Four, high-precision subtraction
1 int gminus (int a[],int b[]);//calculate a=a-b, return symbol bit 0: Positive 1: Negative number 2 {int flag,i 3 flag=compare (A, B);//Call comparison function to determine size 4 if (falg==0) equals 5 {memset (a,0,sizeof (a)); return 0;} If a=b, then a=0, can also add a sentence a[0]=1 before return, which means 1 digits 0 6 if (flag==1)//greater than 7 {for (i=1;i<=a[0];i++) 8 { if ( A[i]<b[i]) {a[i+1]--;a[i]+=10;}//If not sufficiently reduced, borrow a 9 a[i]=a[i]-b[i];} Ten while (a[a[0]]==0) a[0]--;//fixed the number of digits of a to return 0;} if (flag==-1)//is less than a=b-a, returns -113 {for (i=1;i<=b[0];i++) { if (B[i]<a[i]) {b[i+1]--;b[i ]+=10;} If not enough reduction, borrow a a[i]=b[i]-a[i];} a[0]=b[0];16 while (a[a[0]]==0) a[0]--;//fixed the number of digits of a return-1;} 18}
V. High-precision multiplication 1 (high-precision multiply-single-precision number, single-precision number refers to the usual integer number)
1 int multi1 (int a[],long key)//a=a*key,key is a single-precision number 2 {int i,k;3 if (key==0) {memset (a,0,sizeof (a)); A[0]=1;return 0;} Processing key=04 for (i=1;i<=a[0];i++) a[i]=a[i]*key;//first each bit is multiplied by 5 for (i=1;i<=a[0];i++) {a[i+1]+=a[i]/10;a[i]%=10;}// Carry 6//Note the previous statement exits with I=a[0]+17 while (a[i]>0) {a[i+1]=a[i]/10;a[i]=a[i]%10;i++;a[0]++];} Continue processing more than the original a[0] digits, fix the number of digits of a 8 return 0;9}
Six, high precision divided by low precision;
Algorithm: Divide by phase, in order from high to low. In addition to the J-bit, the bit is divided with the divisor after accepting the remainder from the j+1 bit, and if the highest bit is zero, the quotient length is reduced by one. The source program is as follows:
1 #include <stdio.h> 2 #define N 3 main () 4 {5 int A[n] = {0}, C[n] = {0}; 6 int I, K, d, B; 7 Char a1[n]; 8 printf ("Input divisor:"); 9 scanf ("%d", &b), printf ("Input dividend:"), scanf ("%s", A1), K = strlen (A1); i = 0; I < K; i++) A[i] = a1[k-i-1]-' 0 '; d = 0;15 for (i = k-1; I >= 0; i--) + ( d) = d * + a[ I];18 C[i] = d/b;19 d = d% B; (c[k-1] = = 0 && k > 1) k--; printf (" quotient ="); 0 for (i = k-1; I >=; i--) printf ("%d", C[i]), and printf ("\ n remainder =%d", d) ; 25}
Seven, high precision multiplied by high precision (requires the use of as few storage units as possible);
Algorithm: Save two high-precision numbers with an array, then multiply by phase, taking into account the rounding and the total number of digits. The source program is as follows:
1 #include <stdio.h> 2 main () 3 {4 int a[240] = {0}, b[240] = {0}, c[480] = {0}; 5 int i, j, Ka , KB, K; 6 Char a1[240], b1[240]; 7 gets (A1); 8 ka = strlen (A1); 9 gets (B1); Ten KB = strlen (B1), one k = ka + kb;12 for (i = 0; i < ka; i++) a[i] = a1[ka-i-1]-' 0 '; = 0; I < KB; i++) b[i] = b1[kb-i-1]-' 0 '; + for (i = 0; i < ka; i++) (j = 0; J < kb; J + +) + j] = C[i + j] + a[i] * b[j];18 c[i + j +1] = C[i + J +1] + c[i + j]/10;19 c[i + j] = C[i + j]% 10;20 }2 1 if (!c[k]) k--;22 for (i = k-1; I >= 0; i--) printf ("%d", C[i]); 23}
Eight, high precision divided by high precision (requires the use of as few storage units as possible);
Algorithm: The computer simulates the division by hand, and converts the division into a continuous minus.
1 #include <stdio.h> 2 #define N 3 int bj (int a[], int b[], int k1, int k2)/* Compare size function */4 {5 int I, t, Flag; /*flag flag Bit */6 if (K1 < k2) 7 flag = 0; /* Dividend less than divisor returns 0*/8 else if (K1 > K2) 9 flag = 1; /* Dividend greater than divisor returns 1*/-Else 11 {/* is divided by the divisor and the number of digits equal to the bitwise comparison */i = k1; 0; (t = = 0 && i > 0) {+ if (A[i] > B[i]) {t = 1; flag = 1;} 1 7 else if (a[i] = = B[i]) i--; -else {t = 1; flag = 0;} if (i = = 0 && t = = 0) flag = 2; /* Dividend equals the divisor returns 2*/to the return flag; (int a[], int b[], int k1, int k2)/* Subtraction Operation * * * (+ int i, k, d[n]; (i = 0; i < K2; i++ ) D[i] = B[i]; /* Assign the divisor to the array d*/(i = k2; i < N; i++) d[i] = 0; /*d array with no data high position 0*/k = k1-k2-1; /* Calculates the subtraction start position */if (K < 0) k = 0; if (k > 0) + (i = k2-1; I >= 0; i--) d[i + K] = D[i]; /* Move the subtraction digits to the meiotic alignment * * for (i = 0; i < K; i++) d[i] = 0; /* The remaining positions after the move 0*/(i = 0; i < K1; i++) PNs {(A[i] >= d[i]) a[i]-= d[i]; {a[i + 1] = a[i + 1]-1; a[i] = ten + a[i]-d[i]; K}; () A[n () () () () () () () () () () () {0}, B[n] = {0}, C[n] = {0}, D[n] = {0}, x int i, KA, KB, m, T, T1, T2, K, X, KD, Kk Wuyi Char A1[n], b1[n]; printf ("Input dividend:"); scanf ("%s", A1); Si ka = strlen (A1); (i = 0; i < ka; i++) a[i] = a1[ka-i-1]-' 0 '; + printf ("Input divisor:"); scanf ("%s", B1); KB = strlen (B1); (i = 0; i < KB; i++) B[i] = b1[kb-i-1]-' 0 '; kd = ka; /* Save the number of digits */t2 = BJ (A, B, Ka, KB); m = 0; (A[ka-1] = 0) ka--; 66 t = BJ (A, B, Ka, KB); if (t >= 1), (k) = JF (A, B, Ka, KB); c[k]++; if (K > m) m = k; T1 = 0; for (i = k; I <= m; i++) (= x = c[i] + t1; c[i] = x%; t1 = X/10; (T1 > 0) {m++; c[m] = T1; } The Bayi}while (t = = 1); if (t2 = = 0) (the "Business =0") printf ("\ n remainder ="); for (i = kd-1; I >= 0; i--) printf ("%d", a[i]); Exit (1); if (t2 = = 2), ("quotient = 1") printf ("\ n remainder = 0"); (1); 94}: KK = kd; (!c[kd-1]) kd--; ("quotient ="); 98 for (i = kd-1; I >= 0; i--) printf ("%d", c[i]); while (!a[kk]) kk--;100 printf ("\ n remainder ="), 101 if (KK < 0) 102 {103 printf ("0"); 104 exit (1);}106 for (i = KK; I >= 0; i--) printf ("%d", a[i]); 107}
Here are a few examples:
Question 1. N! , it is required to be accurate to P-bit (0〈p〈1000〉.
Algorithm: The result is saved with array A, a[0]=1 at the beginning, multiplied by each of the arrays, and note the change of carry and array length. The source program is as follows:
1 #include <stdio.h> 2 #define M 3 main () 4 {5 int a[m], I, N, j, flag = 1; 6 printf ("n=" ); 7 scanf ("%d", &n), 8 printf ("n!="), 9 a[0] = 1;10 for (i = 1; i < M; i++) A[i] = 0;11 for (j = 2; J <= N; J + +) (i = 0; i < flag; i++) A[i] *= j;14 for (i = 0; i < flag; i++) if (A[i] >= 10) 1 6 { a[i+1] + = a[i]/10;18 a[i] = a[i]% 10;19 if (i = = flag-1) flag++;20 }21 }22 For (j = flag-1; J >= 0; j--) 23
Question 2: number of Mason
"problem description" shape such as 2p-1 is called Mason Number, then p must also be a prime. But the reverse is not necessarily, that is, if p is a prime number, 2p-1 is not necessarily prime. By the end of 1998, 37 Mason had been found. The biggest one is p=3021377, which has 909,526 bits. Mason number has many important applications, which are closely related to the complete number.
Task: Enter P (1000<p<3100000) from the file, calculate the number of bits of 2p-1 and the last 500 digits (expressed in decimal high precision number)
"input Format"
only one integer P (1000<p<3100000) is included in the file
"Output format"
First line: decimal high-precision number of digits 2p-1.
第2-11: The last 500 digits of the decimal high-precision number 2p-1. (output 50 bits per line, output 10 lines, less than 500 bits when the high 0)
you do not have to verify that 2p-1 and p are prime numbers.
"Input Sample"
1279
"output Example"
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
algorithm: The power of 2 can be converted to left-shift operation, in order to improve the speed of operation, you can move the left 10 bits each time, that is, 210. For single-digit consideration, move left one at a time. The source program is as follows:
1 #include <stdio.h> 2 #include <math.h> 3 #define MAX 100000 4 main () 5 {6 int p; 7 int i, J; 8 scanf ("%d", &p); 9 printf ("%d\n", (int) (P * LOG10 (2.0)) + 1); ten long store[110] = {0};11 Store[0] = 1;12 int left = p% 10;13 P/= 10;14 for (i = 1; I <= p; i++) (j = 0; J <=; j + +) Store[j] <<= 10; for (j = 0; J <=, J + +), {store[j] >= MAX) {store[j + 1] + = s TORE[J]/max;23 store[j]%= max;24}25}26}27 for (i = 1; I <= left; i++) 28 {29 for (j = 0; J <=, J + +) Store[j] <<= 1;31 for (j = 0; J <=; J + +) 32 {33 if (Store[j] >= MAX) {store[j + 1] + = Store[j]/max;36 store[j]%= max;37}38 }39}40 store[0]-= 1;41 for (i = 1; i <; i++) [+] (Store[i-1] < 0) 44 {45 Store[i]-= 1;46 store[i-1] + = max;47}48 else49 break;50}51 for (i =; I >= 0; i--) ("%05d", "Store[i"); ((100-i)% = = 0) ("\ n"); 56}57}
Question 3. There is a positive integer n (n can reach 120 bits), which is obtained by multiplying a number of positive integers not greater than 65535. Please decompose this number into the product of prime factor (mass factor).
Input: The input file has a value of only one behavior N.
Output: (1) prime factor from small to large branch output;
(2) Each line outputs a prime factor and the number of the prime factor, separated by a space;
(3) If the decomposition of a positive integer n has more than a prime number greater than 65535, follow the requirements of (1), (2) output decomposition of less than 65535 primes, the next line of output
The DATA error! ”。
Algorithm: First of all the primes between 2 and 65535 are stored in the array, using this number to remove each number in the array, to obtain a qualitative factor to print out. The source program is as follows:
1 #include <stdio.h> 2 #include <math.h> 3 int length, temp[120]; 4 int Sushu (int a[]) 5 {6 int i, j, k = 0, M; 7 for (i = 2; I <= 65537; i++) 8 {9 m = sqrt (i); ten for (j = 2; J <= M; J + +) if (i% j = 0) break;12 if (J > m)-{A[k] = i;15 k++; +}18 return k; }20 int divide (int a[], int k) {10 int i, d = 0;23 for (i = length-1; I >= 0; i--): {d = d * + a[i];26 Temp[i] = d/k;27 D = d% K; if (!d) (temp[length-1] = = 0 && length > 1) length--;32 for (i = 0; i < length; i++) {A[i] = temp[i];35 Temp[i] = 0; }37 for (i = length; i <; i++) a[i] = 0; }39 Else (i = 0; i < length; i++) temp[i] = 0;41 return D; }43 main () () () () () () () () (), K, S, D; /*s counter; d remainder */46 int a[6600], b[120] = {0}, c[120] = {0};47 cHar b1[120];48 gets (B1), the length = strlen (B1), the (i = 0; i < length; i++) B[i] = b1[length-i-1]-' 0 '; 51 K = Sushu (a); * for (i = 0; i < K; i++): 0;55 d = Divide (b, a[i]), and (!d) 57 {58 s++;59 d = Divide (b, a[i]); }61 if (i = = k-1) ("Data error!") BREAK;66}
Turn: zero-based algorithm: high-precision computing