// 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];
}
Esempio n. 2
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);
  }
}