// convert factorized form to number void bs_mul(mpz_t r, long int a, long int b) { long int i, j; if (b-a<=32) { mpz_set_ui(r, 1); for (i=a; i<b; i++) for (j=0; j<fmul[0].pow[i]; j++) mpz_mul_ui(r, r, fmul[0].fac[i]); } else { mpz_t r2; mpz_init(r2); bs_mul(r2, a, (a+b)/2); bs_mul(r, (a+b)/2, b); mpz_mul(r, r, r2); mpz_clear(r2); } }
/* 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); } }