Listing 5: Division of BigNum by another BigNum
//divide a bignum by another bignum BigNum BigNum::operator/(const BigNum &denom){ BigNum q; q.positive = (this->positive == denom.positive); if (abs(*this)<abs(denom)) return q; if (denom.exp <= 0){ //denom is a long; //send it to the easy routine long x = denom.x[0]; return (*this/x); }else{ delete[] q.x; q.exp = this->exp - denom.exp; q.x = new int[q.exp+1]; long qhat; int qpos = q.exp; long d = BASE/(denom.x[denom.exp]+1); //d is a normalizer BigNum u(*this); //make a copy of the numerator BigNum v(denom); //make a copy of the denominator long start = u.exp+1; u = u*d; v = v*d; if (u.exp<start){ u.exp = start; u.x[start]=0;} for(;;){ if (abs(u)<abs(v)){ //when u<v we can't divide anymore u = u/d; //unnormalize u to get remainder return q; } int i = 0; long stop; while(u.x[start+i]==v.x[v.exp+i] && v.exp+i)i--; if (u.x[start+i] < v.x[v.exp+i])stop = start - v.exp -1; else stop = start - v.exp; qhat = long(u.x[start]); //make a guess at qhat qhat = qhat*BASE + u.x[start-1];qhat/=v.x[v.exp]; if (qhat > BASE-1) qhat = BASE-1; long temp; //fast check to see if qhat is too big if (start-1) temp = u.x[start-2]; else temp = 0; while (long(v.x[v.exp-1])*qhat>(long(u.x[start])*BASE + u.x[start-1]-qhat*long(v.x[v.exp]))*BASE + temp) qhat--; BigNum work(v*qhat,u.exp); //qhat still too big?? while(start-stop < work.exp){--qhat; work = work - v;} long borrow = 0; //subtract work from u work.x[work.exp+1] = 0; for(i=stop;i<=start; i++){ temp = long(u.x[i]) - long(work.x[i-stop]) + borrow; if (temp < 0){borrow = -1;temp+=BASE;} else borrow = 0; u.x[i] = temp; } v.x[v.exp+1] = 0; while (borrow < 0 && qhat){//oops qhat was still too big //add back qhat--; long carry = 0; for(i=stop;i<=start; i++){ temp = u.x[i] + v.x[i-stop] + carry; carry = temp/BASE; u.x[i] = temp % BASE; } borrow += carry; } q.x[qpos--] = qhat; start = --u.exp; //work on next digit of u } } } //End of File