// f *= g inline void fac_mul(fac_t f, fac_t g) { fac_t tmp; fac_resize(fmul, f[0].num_facs + g[0].num_facs); fac_mul2(fmul, f, g); tmp[0] = f[0]; f[0] = fmul[0]; fmul[0] = tmp[0]; }
/* f /= gcd(f,g), g /= gcd(f,g) */ void fac_remove_gcd(mpz_t p, fac_t fp, mpz_t g, fac_t fg) { long int i, j, k, c; fac_resize(fmul, min(fp->num_facs, fg->num_facs)); for (i=j=k=0; i<fp->num_facs && j<fg->num_facs; ) { if (fp->fac[i] == fg->fac[j]) { c = min(fp->pow[i], fg->pow[j]); fp->pow[i] -= c; fg->pow[j] -= c; fmul->fac[k] = fp->fac[i]; fmul->pow[k] = c; i++; j++; k++; } else if (fp->fac[i] < fg->fac[j]) { i++; } else { j++; } } fmul->num_facs = k; assert(k <= fmul->max_facs); if (fmul->num_facs) { bs_mul(gcd, 0, fmul->num_facs); #if HAVE_DIVEXACT_PREINV mpz_invert_mod_2exp (mgcd, gcd); mpz_divexact_pre (p, p, gcd, mgcd); mpz_divexact_pre (g, g, gcd, mgcd); #else #define SIZ(x) x->_mp_size mpz_divexact(p, p, gcd); mpz_divexact(g, g, gcd); #endif fac_compact(fp); fac_compact(fg); } }