void modinv(mpz_t r, mpz_t x, mpz_t m) { int iter = 1; mpz_t x1, x3, m1, m3, t1, t3, q; mpz_init_set_ui(x1, 1L); mpz_init_set(x3, x); mpz_init(m1); mpz_init_set(m3, m); mpz_init(t1); mpz_init(t3); mpz_init(q); // Loop while m3 != 0 int kk = 0; while (mpz_sgn(m3) != 0) { // Divide and "Subtract" mpz_fdiv_qr(q, t3, x3, m3); mpz_mul(t1, q, m1); mpz_add(t1, t1, x1); // Swap mpz_swap(x1, m1); mpz_swap(m1, t1); mpz_swap(x3, m3); mpz_swap(m3, t3); iter = -iter; ++kk; } // Make sure x3 = gcd(x,m) == 1 if (mpz_cmp_ui(x3, 1L) != 0) { // Error: No inverse exists mpz_set_ui(r, 0L); goto end; } // Ensure a positive result if (iter < 0) mpz_sub(r, m, x1); else mpz_set(r, x1); end: mpz_clear(x1); mpz_clear(x3); mpz_clear(m1); mpz_clear(m3); mpz_clear(t1); mpz_clear(t3); mpz_clear(q); }
void check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y) { int swap, wneg, xneg, yneg; MPZ_CHECK_FORMAT (w); MPZ_CHECK_FORMAT (x); MPZ_CHECK_FORMAT (y); for (swap = 0; swap < 2; swap++) { for (wneg = 0; wneg < 2; wneg++) { for (xneg = 0; xneg < 2; xneg++) { for (yneg = 0; yneg < 2; yneg++) { check_one (w, x, y); if (mpz_fits_ulong_p (y)) check_one_ui (w, x, mpz_get_ui (y)); mpz_neg (y, y); } mpz_neg (x, x); } mpz_neg (w, w); } mpz_swap (x, y); } }
static void JS_2(int PK, int PL, int PM, int P) { int I, J, K; for (I = 0; I < PL; I++) { K = 2 * I % PK; /* MontgomeryMult(aiJS[I], aiJS[I], biTmp); */ /* AddBigNbrModN(aiJX[K], biTmp, aiJX[K], TestNbr, NumberLength); */ /* AddBigNbrModN(aiJS[I], aiJS[I], biT, TestNbr, NumberLength); */ mpz_mul(biTmp, aiJS[I], aiJS[I]); mpz_add(aiJX[K], aiJX[K], biTmp); mpz_add(biT, aiJS[I], aiJS[I]); for (J = I + 1; J < PL; J++) { K = (I + J) % PK; /* MontgomeryMult(biT, aiJS[J], biTmp); */ /* AddBigNbrModN(aiJX[K], biTmp, aiJX[K], TestNbr, NumberLength); */ mpz_mul(biTmp, biT, aiJS[J]); mpz_add(aiJX[K], aiJX[K], biTmp); } } for (I = 0; I < PK; I++) { /* aiJS[I] = aiJX[I]; */ /* aiJX[I] = 0; */ mpz_swap(aiJS[I], aiJX[I]); mpz_set_ui(aiJX[I], 0); } NormalizeJS(PK, PL, PM, P); }
void C_BigInt::floorDivideInPlace (const C_BigInt inDivisor, C_BigInt & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; mpz_fdiv_qr (quotient, outRemainder.mGMPint, mGMPint, inDivisor.mGMPint) ; mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; }
void eu065(char *ans) { int N = 99; mpz_t n, d, r; mpz_init(n); mpz_init(d); mpz_init(r); mpz_set_ui(n, eterm(N)); mpz_set_ui(d, 1); for (int i = N-1; i >= 0; i--) { mpz_swap(n, d); int t = eterm(i); mpz_addmul_ui(n, d, t); mpz_gcd(r, n, d); mpz_div(n, n, r); mpz_div(d, d, r); } sprintf(ans, "%d", digitsum(n)); mpz_clear(r); mpz_clear(d); mpz_clear(n); }
/* p[0] <-> p[n-1], p[1] <-> p[n-2], ... */ void list_revert (listz_t p, unsigned int n) { unsigned int i; for (i = 0; i < n - 1 - i; i++) mpz_swap (p[i], p[n - 1 - i]); }
void list_swap (listz_t p, listz_t q, unsigned int n) { unsigned int i; for (i = 0; i < n; i++) mpz_swap (p[i], q[i]); }
static void e_mpq_den (mpq_ptr w, mpq_srcptr x) { if (w == x) mpz_swap (mpq_numref(w), mpq_denref(w)); else mpz_set (mpq_numref(w), mpq_denref(x)); mpz_set_ui (mpq_denref(w), 1L); }
int jacobi(mpz_t aa, mpz_t nn) // Generalization of Legendre's symbol. { mpz_t a, n, n2; mpz_init_set(a, aa); mpz_init_set(n, nn); mpz_init(n2); if (mpz_divisible_p(a, n)) return 0; // (0/n) = 0 int ans = 1; if (mpz_cmp_ui(a, 0) < 0) { mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n) if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3 ans = -ans; // (-1/n) = -1 if n = 3 (mod 4) } if (mpz_cmp_ui(a, 1) == 0) { mpz_clear(a); mpz_clear(n); mpz_clear(n2); return ans; // (1/n) = 1 } while (mpz_cmp_ui(a, 0) != 0) { if (mpz_cmp_ui(a, 0) < 0) { mpz_neg(a, a); // (a/n) = (-a/n)*(-1/n) if (mpz_congruent_ui_p(n, 3, 4)) // if n%4 == 3 ans = -ans; // (-1/n) = -1 if n = 3 ( mod 4 ) } while (mpz_divisible_ui_p(a, 2)) { mpz_divexact_ui(a, a, 2); // a = a/2 if (mpz_congruent_ui_p(n, 3, 8) || mpz_congruent_ui_p(n, 5, 8)) // n%8==3 || n%8==5 ans = -ans; } mpz_swap(a, n); // (a,n) = (n,a) if (mpz_congruent_ui_p(a, 3, 4) && mpz_congruent_ui_p(n, 3, 4)) // a%4==3 && n%4==3 ans = -ans; mpz_mod(a, a, n); // because (a/p) = (a%p / p ) and a%pi = (a%n)%pi if n % pi = 0 mpz_cdiv_q_ui(n2, n, 2); if (mpz_cmp(a, n2) > 0) // a > n/2 mpz_sub(a, a, n); // a = a-n } int cmp = mpz_cmp_ui(n, 1); mpz_clear(a); mpz_clear(n); mpz_clear(n2); if (cmp == 0) return ans; return 0; }
/** * Stein's binary greatest common divisor algorithm */ void cpt_bin_gcd(mpz_t res, mpz_srcptr a, mpz_srcptr b) { mpz_t x,y,p,r; mpz_init(x); mpz_init(y); mpz_init(r); mpz_abs(x,a); mpz_abs(y,b); if(mpz_cmp_si(x,0) == 0) { mpz_set(res,y); mpz_clear(x); mpz_clear(y); mpz_clear(r); return; } if(mpz_cmp_si(y,0) == 0) { mpz_set(res,x); mpz_clear(x); mpz_clear(y); mpz_clear(r); return; } mpz_init_set_si(p,1); while(mpz_even_p(x) && mpz_even_p(y)) { mpz_divexact_ui(x,x,2); mpz_divexact_ui(y,y,2); mpz_mul_ui(p,p,2); } while(mpz_even_p(x)) mpz_divexact_ui(x,x,2); while(mpz_even_p(y)) mpz_divexact_ui(y,y,2); if(mpz_cmp(x,y) > 0) mpz_swap(x,y); while(mpz_cmp_si(x,0) > 0) { mpz_sub(r,y,x); while(mpz_cmp_si(r,0) && mpz_even_p(r)) mpz_divexact_ui(r,r,2); if(mpz_cmp(r,x) >= 0) mpz_set(y,r); else { mpz_set(y,x); mpz_set(x,r); } } mpz_mul(res,p,y); mpz_clear(x); mpz_clear(y); mpz_clear(p); mpz_clear(r); }
void C_BigInt::operator %= (const C_BigInt inDivisor) { mpz_t quotient ; mpz_init (quotient) ; mpz_t remainder ; mpz_init (remainder) ; mpz_tdiv_qr (quotient, remainder, mGMPint, inDivisor.mGMPint) ; mpz_swap (remainder, mGMPint) ; mpz_clear (quotient) ; mpz_clear (remainder) ; }
/*--------------------------------------------------------------------*/ static uint32 postprocess(msieve_obj *obj, mpz_t factor, mpz_t n, pm1_pp1_t *non_ecm_vals, factor_list_t *factor_list) { /* handling for factors found. When complete, n is changed to new input to be factored */ uint32 i; mpz_t q, r; mp_t mp_factor; uint32 is_prime0, is_prime1; /* divide out all instances of factor from n */ mpz_init(q); mpz_init(r); while (1) { mpz_tdiv_qr(q, r, n, factor); if (mpz_cmp_ui(q, (unsigned long)0) == 0 || mpz_cmp_ui(r, (unsigned long)0) != 0) break; mpz_set(n, q); } mpz_clear(q); mpz_clear(r); if (mpz_cmp_ui(n, (unsigned long)1) == 0) { mpz_set(n, factor); } else { /* in the worst case, n and factor are both composite. We would have to give up factoring one of them and continue on the other */ is_prime0 = mpz_probab_prime_p(factor, 1); is_prime1 = mpz_probab_prime_p(n, 1); if ( (is_prime1 > 0 && is_prime0 == 0) || (is_prime1 == 0 && is_prime0 == 0 && mpz_cmp(factor, n) > 0) ) { mpz_swap(factor, n); } /* switch the P+-1 stage 1 values to be modulo the new n */ for (i = 0; i < NUM_NON_ECM; i++) { mpz_mod(non_ecm_vals[i].start_val, non_ecm_vals[i].start_val, n); } } gmp2mp(factor, &mp_factor); return factor_list_add(obj, factor_list, &mp_factor); }
void C_BigInt::divideInPlace (const uint32_t inDivisor, uint32_t & outRemainder) { mpz_t quotient ; mpz_init (quotient) ; if (mpz_sgn (mGMPint) >= 0) { outRemainder = (uint32_t) mpz_fdiv_q_ui (quotient, mGMPint, inDivisor) ; }else{ outRemainder = (uint32_t) mpz_cdiv_q_ui (quotient, mGMPint, inDivisor) ; } mpz_swap (quotient, mGMPint) ; mpz_clear (quotient) ; }
int dothedir(const char *path,mpz_t size, int output, unsigned int depth){ DIR *d; struct dirent *de; mpz_t cursize; mpz_t tmpsize; char tmppath[PATH_MAX+1]; size_t pathsize; /* try to open the dir */ d=opendir(path); if(!d) return 2; /* calculate the pathsize and return an error if > PATH_MAX */ pathsize=strlen(path); if(path[pathsize-1]!='/') pathsize+=1; if(pathsize>PATH_MAX) return 3; /* copy the path to tmppath and add a '/' if needed */ strcpy(tmppath,path); if(path[pathsize-1]!='/') strcat(tmppath,"/"); /* start with cursize of 0 */ mpz_init_set_ui(cursize,0); mpz_init(tmpsize); /* for each directory entry... */ while(de=readdir(d)) /* if the entry is not "." or ".."... */ if( strcmp(de->d_name,".") && strcmp(de->d_name,"..") ){ /* if the resultant path will be larger than PATH_MAX return an error */ if(strlen(de->d_name)+pathsize > PATH_MAX){ mpz_clear(cursize); /* free cursize */ mpz_clear(tmpsize); /* free tmpsize */ return 3; } strcat(tmppath,de->d_name); /* add the entry to the path */ if(!dothepath(tmppath,tmpsize,0,depth)) /* handle the new path */ mpz_add(cursize,cursize,tmpsize); /* add to tally if successful */ tmppath[pathsize]=0; /* remove the entry from the path */ } closedir(d); /* close the directory */ if(output || opt_outputall) printpath(cursize,path); /* output the result */ mpz_swap(size,cursize); /* return the result */ mpz_clear(cursize); /* free cursize */ mpz_clear(tmpsize); /* free tmpsize */ return 0; }
static PyObject * Pyxmpz_make_mpz(PyObject *self, PyObject *other) { PympzObject* result; if (!(result = (PympzObject*)Pympz_new())) return NULL; mpz_swap(result->z, Pympz_AS_MPZ(self)); mpz_set_ui(Pympz_AS_MPZ(self), 0); return (PyObject*)result; }
//------------------------------------------------------------------------------ // Name: cmp //------------------------------------------------------------------------------ knumber_base *knumber_integer::cmp() { #if 0 // unfortunately this breaks things pretty badly // for non-decimal modes :-( mpz_com(mpz_, mpz_); #else mpz_swap(mpz_, knumber_integer(~toUint64()).mpz_); #endif return this; }
void compute_s (mpz_t s, unsigned long B1) { mpz_t acc[MAX_HEIGHT]; /* To accumulate products of prime powers */ unsigned int i, j; unsigned long pi = 2, pp, maxpp; ASSERT_ALWAYS (B1 < MAX_B1_BATCH); for (j = 0; j < MAX_HEIGHT; j++) mpz_init (acc[j]); /* sets acc[j] to 0 */ i = 0; while (pi <= B1) { pp = pi; maxpp = B1 / pi; while (pp <= maxpp) pp *= pi; if ((i & 1) == 0) mpz_set_ui (acc[0], pp); else mpz_mul_ui (acc[0], acc[0], pp); j = 0; /* We have accumulated i+1 products so far. If bits 0..j of i are all set, then i+1 is a multiple of 2^(j+1). */ while ((i & (1 << j)) != 0) { /* we use acc[MAX_HEIGHT-1] as 0-sentinel below, thus we need j+1 < MAX_HEIGHT-1 */ ASSERT (j + 1 < MAX_HEIGHT - 1); if ((i & (1 << (j + 1))) == 0) /* i+1 is not multiple of 2^(j+2), thus add[j+1] is "empty" */ mpz_swap (acc[j+1], acc[j]); /* avoid a copy with mpz_set */ else mpz_mul (acc[j+1], acc[j+1], acc[j]); /* accumulate in acc[j+1] */ mpz_set_ui (acc[j], 1); j++; } i++; pi = getprime (pi); } for (mpz_set (s, acc[0]), j = 1; mpz_cmp_ui (acc[j], 0) != 0; j++) mpz_mul (s, s, acc[j]); getprime_clear (); /* free the prime tables, and reinitialize */ for (i = 0; i < MAX_HEIGHT; i++) mpz_clear (acc[i]); }
void check_sequence (int argc, char *argv[]) { unsigned long n; unsigned long limit = 100 * BITS_PER_MP_LIMB; mpz_t want_ln, want_ln1, got_ln, got_ln1; if (argc > 1 && argv[1][0] == 'x') limit = ULONG_MAX; else if (argc > 1) limit = atoi (argv[1]); /* start at n==0 */ mpz_init_set_si (want_ln1, -1); /* L[-1] */ mpz_init_set_ui (want_ln, 2); /* L[0] */ mpz_init (got_ln); mpz_init (got_ln1); for (n = 0; n < limit; n++) { mpz_lucnum2_ui (got_ln, got_ln1, n); MPZ_CHECK_FORMAT (got_ln); MPZ_CHECK_FORMAT (got_ln1); if (mpz_cmp (got_ln, want_ln) != 0 || mpz_cmp (got_ln1, want_ln1) != 0) { printf ("mpz_lucnum2_ui(%lu) wrong\n", n); mpz_trace ("want ln ", want_ln); mpz_trace ("got ln ", got_ln); mpz_trace ("want ln1", want_ln1); mpz_trace ("got ln1", got_ln1); abort (); } mpz_lucnum_ui (got_ln, n); MPZ_CHECK_FORMAT (got_ln); if (mpz_cmp (got_ln, want_ln) != 0) { printf ("mpz_lucnum_ui(%lu) wrong\n", n); mpz_trace ("want ln", want_ln); mpz_trace ("got ln", got_ln); abort (); } mpz_add (want_ln1, want_ln1, want_ln); /* L[n+1] = L[n] + L[n-1] */ mpz_swap (want_ln1, want_ln); } mpz_clear (want_ln); mpz_clear (want_ln1); mpz_clear (got_ln); mpz_clear (got_ln1); }
/*-------------------------------------------------------------------*/ static void multiply_relations(relation_prod_t *prodinfo, uint32 index1, uint32 index2, gmp_poly_t *prod) { /* multiply together the relations from index1 to index2, inclusive. We proceed recursively to assure that polynomials with approximately equal- size coefficients get multiplied, and also to avoid wasting huge amounts of memory in the beginning when all the polynomials are small but the memory allocated for them is large */ uint32 i; gmp_poly_t prod1, prod2; if (index1 == index2) { /* base case of recursion */ relation_to_poly(prodinfo->rlist + index1, prodinfo->c, prod); return; } gmp_poly_init(&prod1); gmp_poly_init(&prod2); if (index1 == index2 - 1) { /* base case of recursion */ relation_to_poly(prodinfo->rlist + index1, prodinfo->c, &prod1); relation_to_poly(prodinfo->rlist + index2, prodinfo->c, &prod2); } else { /* recursively compute the product of the first half and the last half of the relations */ uint32 mid = (index1 + index2) / 2; multiply_relations(prodinfo, index1, mid, &prod1); multiply_relations(prodinfo, mid + 1, index2, &prod2); } /* multiply them together and save the result */ gmp_poly_mul(&prod1, &prod2, prodinfo->monic_poly, 1); for (i = 0; i <= prod1.degree; i++) mpz_swap(prod->coeff[i], prod1.coeff[i]); prod->degree = prod1.degree; gmp_poly_clear(&prod1); gmp_poly_clear(&prod2); }
void swap_relation (relation r, relation s) { int *t; unsigned int *u; unsigned int v; mpz_swap (r->x, s->x); t = r->p; r->p = s->p; s->p = t; u = r->e; r->e = s->e; s->e = u; v = r->a; r->a = s->a; s->a = v; v = r->n; r->n = s->n; s->n = v; }
/** * Euclid's greatest common divisor algorithm */ void cpt_gcd(mpz_t res, mpz_srcptr a, mpz_srcptr b) { mpz_t aa, ab; /*************Initialization********/ mpz_init(aa); /*aa = |a|*/ mpz_init(ab); /*ab = |b|*/ mpz_abs(aa,a); mpz_abs(ab,b); /*If a > b, exchange them*/ if(mpz_cmp(aa,ab) > 0) mpz_swap(aa,ab); while(mpz_cmp_si(aa,0) > 0) { mpz_mod(ab,ab,aa); mpz_swap(aa,ab); } mpz_set(res,ab); /***************Clear**************/ mpz_clear(aa); mpz_clear(ab); }
void alder_gmp_test() { mpz_t integ1, integ2; mpz_init2 (integ1, 54); mpz_init2 (integ2, 54); mpz_set_ui(integ1, 1); mpz_mul_2exp(integ1, integ1, 65); mpz_out_str (stdout, 2, integ1); printf("\n"); // mpz_add_ui(integ1,integ1,1); mpz_out_str (stdout, 10, integ1); printf("\n"); // mpz_mul_2exp(integ1, integ1, 2); // mpz_out_str (stdout, 2, integ1); printf("\n"); uint64_t x2[2]; x2[0] = 0; x2[1] = 0; uint64_t x = 0; size_t countp = 0; mpz_export(x2, &countp, -1, 8, 0, 0, integ1); printf("x[0]: %llu\n", x2[0]); printf("x[1]: %llu\n", x2[1]); x = UINT64_MAX; printf("x: %llu\n", x); mpz_set_ui(integ1,0); // mpz_mul_2exp(integ1, integ1, ); // mpz_import(b, 1, 1, sizeof(a), 0, 0, &a); // mpz_export mpz_out_str (stdout, 2, integ1); printf("\n"); mpz_out_str (stdout, 2, integ2); printf("\n"); mpz_swap(integ1, integ2); mpz_mul_2exp(integ2, integ1, 2); mpz_setbit(integ2,0); mpz_setbit(integ2,1); mpz_out_str (stdout, 2, integ2); printf("\n"); mpz_clear (integ1); mpz_clear (integ2); }
//------------------------------------------------------------------------------ // Name: cbrt //------------------------------------------------------------------------------ knumber_base *knumber_integer::cbrt() { mpz_t x; mpz_init_set(x, mpz_); if(mpz_root(x, x, 3)) { mpz_swap(mpz_, x); mpz_clear(x); return this; } mpz_clear(x); knumber_float *f = new knumber_float(this); delete this; return f->cbrt(); }
static PyObject * GMPy_XMPZ_Method_MakeMPZ(PyObject *self, PyObject *other) { MPZ_Object* result; CTXT_Object *context = NULL; CHECK_CONTEXT(context); if (!(result = GMPy_MPZ_New(context))) { return NULL; } mpz_swap(result->z, MPZ(self)); mpz_set_ui(MPZ(self), 0); return (PyObject*)result; }
int rsa_import_key(rsa_private_key_t *key, int endian, uint8_t *n, size_t n_len, uint8_t *e, size_t e_len, uint8_t *p, uint8_t *q) { mpz_t t1, t2, phi; if (n == NULL || n_len == 0 || (p == NULL && q == NULL)) return -1; /* init key */ key->size = n_len << 3; if (e == NULL || e_len == 0) { mpz_init_set_ui(key->e, 65537); } else { mpz_init2(key->e, (e_len << 3) + GMP_NUMB_BITS); mpz_import(key->e, e_len, endian, 1, 0, 0, e); } mpz_init2(key->n, key->size + GMP_NUMB_BITS); mpz_init2(key->p, key->size / 2 + GMP_NUMB_BITS); mpz_init2(key->q, key->size / 2 + GMP_NUMB_BITS); mpz_init2(key->d, key->size + GMP_NUMB_BITS); mpz_init2(key->u, key->size / 2 + GMP_NUMB_BITS); mpz_init2(t1, key->size / 2 + GMP_NUMB_BITS); mpz_init2(t2, key->size / 2 + GMP_NUMB_BITS); mpz_init2(phi, key->size + GMP_NUMB_BITS); /* import values */ mpz_import(key->n, n_len, endian, 1, 0, 0, n); if (p != NULL) mpz_import(key->p, n_len / 2, endian, 1, 0, 0, p); if (q != NULL) mpz_import(key->q, n_len / 2, endian, 1, 0, 0, q); if (p == NULL) mpz_tdiv_q(key->p, key->n, key->q); if (q == NULL) mpz_tdiv_q(key->q, key->n, key->p); /* p shall be smaller than q */ if (mpz_cmp(key->p, key->q) > 0) mpz_swap(key->p, key->q); /* calculate missing values */ mpz_sub_ui(t1, key->p, 1); mpz_sub_ui(t2, key->q, 1); mpz_mul(phi, t1, t2); mpz_invert(key->d, key->e, phi); mpz_invert(key->u, key->p, key->q); /* release helper variables */ mpz_clear(t1); mpz_clear(t2); mpz_clear(phi); /* test key */ if (rsa_test_key(key) != 0) { rsa_release_private_key(key); return -1; } return 0; }
static mul_casc * mulcascade_mul_d (mul_casc *c, const double n, ATTRIBUTE_UNUSED mpz_t t) { unsigned int i; if (mpz_sgn (c->val[0]) == 0) { mpz_set_d (c->val[0], n); return c; } mpz_mul_d (c->val[0], c->val[0], n, t); if (mpz_size (c->val[0]) <= CASCADE_THRES) return c; for (i = 1; i < c->size; i++) { if (mpz_sgn (c->val[i]) == 0) { mpz_set (c->val[i], c->val[i-1]); mpz_set_ui (c->val[i-1], 0); return c; } else { mpz_mul (c->val[i], c->val[i], c->val[i-1]); mpz_set_ui (c->val[i-1], 0); } } /* Allocate more space for cascade */ i = c->size++; c->val = (mpz_t*) realloc (c->val, c->size * sizeof (mpz_t)); if (c->val == NULL) { fprintf (stderr, "Cannot allocate memory in mulcascade_mul_d\n"); exit (1); } mpz_init (c->val[i]); mpz_swap (c->val[i], c->val[i-1]); return c; }
static CRATIONAL *_powf(CRATIONAL *a, double f, bool invert) { ulong p; mpz_t num, den; mpq_t n; if (invert || (double)(int)f != f) return NULL; if (f < 0) { f = (-f); invert = TRUE; } p = (ulong)f; mpz_init(num); mpz_pow_ui(num, mpq_numref(a->n), p); mpz_init(den); mpz_pow_ui(den, mpq_denref(a->n), p); mpq_init(n); if (invert) mpz_swap(num, den); if (mpz_cmp_si(den, 0) == 0) { GB.Error(GB_ERR_ZERO); return NULL; } mpq_set_num(n, num); mpq_set_den(n, den); mpz_clear(num); mpz_clear(den); mpq_canonicalize(n); return RATIONAL_create(n); }
/* Select the 2, 4, or 6 numbers we will try to factor. */ static void choose_m(mpz_t* mlist, long D, mpz_t u, mpz_t v, mpz_t N, mpz_t t, mpz_t Nplus1) { int i, j; mpz_add_ui(Nplus1, N, 1); mpz_sub(mlist[0], Nplus1, u); /* N+1-u */ mpz_add(mlist[1], Nplus1, u); /* N+1+u */ for (i = 2; i < 6; i++) mpz_set_ui(mlist[i], 0); if (D == -3) { /* If reading Cohen, be sure to see the errata for page 474. */ mpz_mul_si(t, v, 3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_sub(mlist[2], Nplus1, t); /* N+1-(u+3v)/2 */ mpz_add(mlist[3], Nplus1, t); /* N+1+(u+3v)/2 */ mpz_mul_si(t, v, -3); mpz_add(t, t, u); mpz_tdiv_q_2exp(t, t, 1); mpz_sub(mlist[4], Nplus1, t); /* N+1-(u-3v)/2 */ mpz_add(mlist[5], Nplus1, t); /* N+1+(u-3v)/2 */ } else if (D == -4) { mpz_mul_ui(t, v, 2); mpz_sub(mlist[2], Nplus1, t); /* N+1-2v */ mpz_add(mlist[3], Nplus1, t); /* N+1+2v */ } /* m must not be prime */ for (i = 0; i < 6; i++) if (mpz_sgn(mlist[i]) && _GMP_is_prob_prime(mlist[i])) mpz_set_ui(mlist[i], 0); /* Sort the m values so we test the smallest first */ for (i = 0; i < 5; i++) if (mpz_sgn(mlist[i])) for (j = i+1; j < 6; j++) if (mpz_sgn(mlist[j]) && mpz_cmp(mlist[i],mlist[j]) > 0) mpz_swap( mlist[i], mlist[j] ); }
/* Compute log(2)/log(b) as a fixnum. */ void mp_2logb (mpz_t r, int bi, int prec) { mpz_t t, t2, two, b; int i; mpz_init_set_ui (t, 1); mpz_mul_2exp (t, t, prec+EXTRA); mpz_init (t2); mpz_init_set_ui (two, 2); mpz_mul_2exp (two, two, prec+EXTRA); mpz_set_ui (r, 0); mpz_init_set_ui (b, bi); mpz_mul_2exp (b, b, prec+EXTRA); for (i = prec-1; i >= 0; i--) { mpz_mul_2exp (b, b, prec+EXTRA); mpz_sqrt (b, b); mpz_mul (t2, t, b); mpz_tdiv_q_2exp (t2, t2, prec+EXTRA); if (mpz_cmp (t2, two) < 0) /* not too large? */ { mpz_setbit (r, i); /* set next less significant bit */ mpz_swap (t, t2); /* new value acceptable */ } } mpz_clear (t); mpz_clear (t2); mpz_clear (two); mpz_clear (b); }
void __rat_approx_step(mpq_t res, mpz_t num, mpz_t den, mpz_t a, mpz_t pnm2, mpz_t pnm1, mpz_t qnm2, mpz_t qnm1, mpz_t pn, mpz_t qn) { mpz_tdiv_qr(a,num,num,den); /* pn = an pn-1 + pn-2 * qn = an qn-1 + qn-2 */ mpz_mul(pn,a,pnm1); mpz_add(pn,pn,pnm2); mpz_mul(qn,a,qnm1); mpz_add(qn,qn,qnm2); mpq_set_num(res,pn); mpq_set_den(res,qn); mpq_canonicalize(res); /* Advance: pn-1 -> pn-2, pn -> pn-1, and for q */ mpz_set(pnm2,pnm1); mpz_set(qnm2,qnm1); mpz_set(pnm1,pn); mpz_set(qnm1,qn); mpz_swap(num,den); }