static size_t FFTStretch(Polynomial<T> & p) { size_t n = 1; size_t d = p.Degree(); while (1) { if (d <= n) break; n <<= 1; if (n == 0) Polynomial<T>::Xoverflow(); } n <<= 1; p = p.Stretch(n); return n; }
bool Polynomial::Divide(const Polynomial & divisor_polynomial, Polynomial & quotient_polynomial, Polynomial & remainder_polynomial) const { //------------------------------------------------------------------ // If the divisor is zero then fail. //------------------------------------------------------------------ int divisor_degree = divisor_polynomial.Degree(); bool non_zero_divisor_flag = ((divisor_polynomial.Degree() != 0) || (divisor_polynomial[0] != 0.0)); if (non_zero_divisor_flag) { //-------------------------------------------------------------- // If this dividend polynomial's degree is not greater than // or equal to the divisor polynomial's degree then do the division. //-------------------------------------------------------------- remainder_polynomial = *this; int dividend_degree = Degree(); quotient_polynomial = 0.0; int quotient_maximum_degree = dividend_degree - divisor_degree + 1; quotient_polynomial.SetLength(quotient_maximum_degree); quotient_polynomial.m_degree = -1; double * quotient_coefficient_ptr = quotient_polynomial.m_coefficient_vector_ptr; double * dividend_coefficient_ptr = remainder_polynomial.m_coefficient_vector_ptr; double leading_divisor_coefficient = divisor_polynomial[divisor_degree]; //-------------------------------------------------------------- // Loop and subtract each scaled divisor polynomial // to perform the division. //-------------------------------------------------------------- int dividend_index = dividend_degree; for (dividend_index = dividend_degree; dividend_index >= divisor_degree; --dividend_index) { //---------------------------------------------------------- // Subtract the scaled divisor from the dividend. //---------------------------------------------------------- double scale_value = remainder_polynomial[dividend_index] / leading_divisor_coefficient; //---------------------------------------------------------- // Increase the order of the quotient polynomial. //---------------------------------------------------------- quotient_polynomial.m_degree += 1; int j = 0; for (j = quotient_polynomial.m_degree; j >= 1; --j) { quotient_coefficient_ptr[j] = quotient_coefficient_ptr[j - 1]; } quotient_coefficient_ptr[0] = scale_value; //---------------------------------------------------------- // Subtract the scaled divisor from the dividend. //---------------------------------------------------------- int dividend_degree_index = dividend_index; for (j = divisor_degree; j >=0; --j) { dividend_coefficient_ptr[dividend_degree_index] -= divisor_polynomial[j] * scale_value; --dividend_degree_index; } } //-------------------------------------------------------------- // Adjust the order of the current dividend polynomial. // This is the remainder polynomial. //-------------------------------------------------------------- remainder_polynomial.AdjustPolynomialDegree(); quotient_polynomial.AdjustPolynomialDegree(); } else { quotient_polynomial = DBL_MAX; remainder_polynomial = 0.0; } return non_zero_divisor_flag; }