// ============================================================ // // multiply.cpp // // Copyright 2002, Dennis Meilicke and Rene Peralta // // ============================================================ // // Description: // // Multiplication functions. // // ============================================================ #include #include void Multiply( Base *A, long b ) // // Compute A = A * b // { if( A->size == 0 ) return; if ( b == 0 ) { Assign( A, 0 ); return; } // // Set the sign of the result... // A->sign = ( A->sign == sign( b ) ) ? positive : negative; if( b < 0 ) b = 0 - b; ddSplit_t accum; accum.all = 0; digit_t *a; for ( a=A->digit ; a<(A->digit+A->size) ; a++ ) { accum.all = ( (ddigit_t)*a * (ddigit_t)b ) + accum.dd.high; *a = accum.dd.low; } if( accum.dd.high ) { *a = accum.dd.high; A->size++; } } // ============================================================ // void Multiply( Base *A, unsigned long b ) // // Compute A = A * b // // Note b > 0 // { if( A->size == 0 ) return; if ( b == 0 ) { Assign( A, 0 ); return; } ddSplit_t accum; accum.all = 0; digit_t *a; for( a=A->digit ; a<(A->digit+A->size) ; a++ ) { accum.all = ( (ddigit_t)*a * (ddigit_t)b ) + accum.dd.high; *a = accum.dd.low; } if( accum.dd.high ) { *a = accum.dd.high; A->size++; } } // ============================================================ // void multiply( const Base *A, const Base *B, Base *Prod ) // // sMax is used to avoid having to zero out the array. // It points to the most significant digit of the partial // product. So if the pointer to the current digit is // greater than sMax, the digit is replaced. Otherwise, // the digit is added to. // { if( ( A->size == 0 ) || ( B->size == 0 ) ) { Prod->size = 0; return; } if( A->sign == B->sign ) Prod->sign = positive; else Prod->sign = negative; const digit_t *a, *b; const digit_t *aEnd = A->digit + A->size; const digit_t *bEnd = B->digit + B->size; digit_t *s, *sMax=0, *sBegin; sBegin = Prod->digit; ddSplit_t accum; for( a=A->digit ; adigit, s=sBegin ; b sMax ) sMax = s; else accum.all += *s; *s = accum.dd.low; } *s = accum.dd.high; sMax = s; } Prod->size = A->size + B->size; // // Adjust the size of the product. This is because for // a * b = c, size of c is not necessarily // size of a + size of b. Consider 3 * 3, or 10 * 10. // if( Prod->digit[ Prod->size - 1 ] == 0 ) Prod->size--; }