written calculation multiplication:for M-bit and n-bit inputs. The traditional multiplication needs to m*n the main multiplication, namely the algorithm complexity is O (). When we multiply with paper and pens, we multiply each bit of the multiplier by multiplying each bit of the multiplier with the carry of the previous column to produce an intermediate result of the appropriate shift. Then the result of multiplication is obtained by adding the intermediate results of the rows. For example, the steps for calculating 189*34 in the 10 binary are as follows:
The operation process of written calculation multiplication
The algorithm is calculated according to the above procedure. But it is best to run the internal multiplication and addition in parallel on the computer. That is, the same time that the middle result of each row is calculated, the line is added to the last result. This saves a lot of steps and avoids the spatial overhead of intermediate results and memory management operations, a simple optimization that can improve efficiency to some extent.
The pseudo-code for this algorithm such as the following table:
Input: Large integer x, y with N and t binary digits, respectively Output: Product of the B-binary |
1. I from 0 to n+t-1, place WI = 0 2. I from 0 to T 2.1 J from 0 to N Calculate wi+j=wi+j + xj * Yi If the wi+j is not less than the carry value, The current intermediate value representation is again formatted 3. Return |
Since the product of two 16 bits will exceed the maximum number of 16 bits that can be represented, we know that a 32-bit number can completely preserve the product of two 16-bit numbers, and the pseudo-code above uses a 32-bit to save two 16-bit number products plus two single-word results. The following is a discussion of its security (whether it will overflow): The maximum result of the above expression calculation is (216-1) * (216-1) + (216-1). After simplification is 232-216. is less than the maximum value of a 32-digit number. So a 32-digit number can hold the result of the expression without overflow. The program does not lose precision.
There is a special kind of multiplication in multiplication-self-squared. The use of general calculations for this type of multiplication is naturally feasible, but it can be used in a much quicker way. Using one-time traversal of integers each of them can be used to solve the general multiplication needs nested loops two times the result of the ability processing, because the self-squared two multiplier is "symmetric". Take a (A1A2A3A4) as an example: each bit of multiplication after the operation will have the corresponding bit repeated operation once, for example, A1*A4 will run two times, and the corresponding product results in the same result position accumulated.
Therefore, the efficiency of the self-squared algorithm is higher than that of the general multiplication.
/* Multiplication Operation */int Mulhbint (Hbigint *product, Hbigint *bia, Hbigint *bib) {hbigint bit;//calculation results are first saved in a temporary variable register un_short *pworda = Bia->pbigint;register Un_short *pwordb = bib->pbigint;register Un_short *PPRD = NULL;long result = 0, i = 0, j = 0 ; Initialize the transient large integer variable if (result = Inithbint (&bit,bia->length + bib->length))! = return_ok_bint) RETURN result; Bit.length = bia->length + bib->length;bit.sign = (Bia->sign = = bib->sign)? 1:-1; The same number is positive, the number is negative PPRD = Bit.pbigint;for (i=0; i<bia->length; ++i) {//the product for (j=0; j<bib->length; ++j) is calculated as a traditional paper-pen multiplication method {Pprd[i+j] = Pprd[i+j] + pworda[i] * pwordb[j];//Assuming that the unit length can represent the maximum value (in this case, 2<<16), one time format is processed if (Pprd[i+j] >> bit_ Pre_word) Formathbint (&bit);}} Formathbint (&bit); Trimhbint (&bit);//Remove High-level invalid 0extendHBInt (product,bit.length); Assignhbint (Product, &bit);d eletehbint (&bit); Clears the temporary variable RETURN return_ok_bint;}
Written Calculation Division:
This algorithm is modeled as a form of written calculation division. Deformed. Based on the characteristics of written calculation division. We know that the most important and difficult step is the estimation of the quotient.
We do division, is based on the dividend and the divisor of the highest number of trial quotient, this algorithm is also used in this way. At the time of the trial business. To lift the speed. Attempts to use the quotient cannot be started from 1 until I,i is satisfied.
This operation uses the binary lookup method to test the quotient. Thus increasing the speed.
In addition to the trial business, another difficulty is to the divisor of the bit alignment. In most operations, the number of bits in the divisor is less than the divisor, so it is necessary to move the divisor to the left before the trial is done, that is, the person is the multiplier (Bn) to enlarge the divisor. As for the left shift in detail, it is necessary to determine the high level. Rules such as the following:
Input: Large integer x (divisor), Y (dividend) of two B-ary (bits m, N) x=m1m2. Mm,y=n1n2...nn Output: Left shift number L |
1. By default M < N, initialize L=N-M 2. The high part of the two number: 2.1 Comparison of M1 and N1 If M1 > N1 are L=L-1 If M1 = N1 then set i from 0. L If Mi > ni are l=l-1 Otherwise, end the loop 3. Return to L |
/* Division operation a Dividend B divisor c quotient D remainder */int divhbint (hbigint *a, Hbigint *b, Hbigint *c, Hbigint *d) {hbigint ta,tb,tc,temp,tc_1; Temporary variable long result=0,first=1,middle=0,last=0;un_short mark=0;long len_ta,len_tb,len,i;int re;if (0 = = B->length | | (1 = = B->length && 0 = = b->pbigint[0])) return-1; The divisor cannot be a 0//divisor of 1. The quotient equals dividend, the remainder is 0if (1 = = B->length && 1 = = B->pbigint[0]) {assignhbint (c,a); Setzerohbint (d); Hbi_add_int (d,0) ; return return_ok_bint;} Re = Comparehbint (A, b); if ( -1 = = re) {//divisor is greater than dividend, quotient is 0. The remainder is dividend setzerohbint (c); Assignhbint (d,a); return return_ok_bint;} if (0 = = re) {//divisor equals dividend, quotient is 1, remainder is 0setZeroHBInt (c); Setzerohbint (d); Hbi_add_int (c,1); Hbi_add_int (d,0); return Return_ok_ BINT;} Initialize the temporary variable inithbint (&ta,initial_bint); Inithbint (&tb,initial_bint); Inithbint (&tc,initial_bint); Inithbint (&temp,initial_bint); Inithbint (&tc_1,initial_bint); Len_ta=ta.length;len_tb=ta.length;len=len_ Ta-len_tb;i=0;assignhbint (&ta,a);//Assign Assignhbint (&TB,B) to the temporary variable, hbi_add_int (&tc,1);//initial quotient is 1Extendhbint (&temp,ta.length);//Extended temporary variable length extendhbint (&tc_1,ta.length);//dichotomy Trial quotient calculation while (Comparehbint (& TA,B) > 0) {//guarantee TA is greater than B cycle len_ta=ta.length;len_tb=tb.length;len=len_ta-len_tb;i=0;mark=0;if (Ta.pbigint[len_ta-1] <= Tb.pbigint[len_tb-1]) {while (I<LEN_TB) {if (Ta.pbigint[len_ta-1-i] < tb.pbigint[len_tb-1-i]) {mark= Ta.pbigint[len_ta-1];len--;i++;break;} else i++;}} Left_shift_word (&tb,len);//The divisor is left shifted. So that it has the same number of Left_shift_word (&tc,len) as the dividend;//quotient at the same time left shift result=mark*carry_radix+ta.pbigint[len_ta-1-i];first=1;last= Result/tb.pbigint[len_tb-1+len] + 1;//The upper limit middle= (Last+first)/2 + 1;//binary lookup for the median for (; (First < last) && (first! = middle); ) {//Use the binary lookup method to try the Assignhbint (&TEMP,&TB); Hbi_mul_radix (&temp,middle); if ( -1 = = Comparehbint (&ta,& temp)) Last=middle;else first=middle;middle= (Last+first)/2;} Assignhbint (&TEMP,&TB); Hbi_mul_radix (&temp,middle); Subhbint (&ta,&ta,&temp);//divisor-divisor * Shang Hbi_mul_radix (&tc,middle); Get the trial of the vendor addHbint (&TC_1,&TC_1,&TC);//To the quotient of the cumulative setzerohbint (&TC); The value of the temporary depositary 0hbi_add_int (&tc,1);//1 Setzerohbint (&temp) for the temporary variable of the quotient; Assignhbint (&tb,b);} if (Comparehbint (&ta,b) = = 0) {hbi_add_int (c,1); Setzerohbint (d);} else {if (c!=null) assignhbint (c,&tc_1);// The quotient if (d!=null) Assignhbint (D,&TA) of the division operation is obtained;//the remainder of the division operation}//Reclaim the temporal variable Space deletehbint (&TA); Deletehbint (&TB);d eletehbint (&TC);d eletehbint (&tc_1);d eletehbint (&temp); return return_ok_bint;}
The multiplication and addition of the basic arithmetic algorithm for the super-long integer