static PyObject * Pygmpy_f_divmod(PyObject *self, PyObject *args) { PyObject *x, *y, *result; PympzObject *q, *r, *tempx, *tempy; if(PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("f_divmod() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); CREATE_TWO_MPZ_TUPLE(q, r, result); if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("f_divmod() division by 0"); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } mpz_fdiv_qr(q->z, r->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y)); } else { tempx = Pympz_From_Integer(x); tempy = Pympz_From_Integer(y); if (!tempx || !tempy) { TYPE_ERROR("f_divmod() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("f_divmod() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); Py_DECREF((PyObject*)r); Py_DECREF(result); return NULL; } mpz_fdiv_qr(q->z, r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } PyTuple_SET_ITEM(result, 0, (PyObject*)q); PyTuple_SET_ITEM(result, 1, (PyObject*)r); return result; }
ring_elem RingZZ::remainderAndQuotient(const ring_elem f, const ring_elem g, ring_elem ") const { mpz_ptr q = new_elem(); mpz_ptr r = new_elem(); int gsign = mpz_sgn(g.get_mpz()); mpz_t gg, ghalf; mpz_init(gg); mpz_init(ghalf); mpz_abs(gg,g.get_mpz()); mpz_fdiv_qr(q, r, f.get_mpz(), gg); mpz_tdiv_q_2exp(ghalf, gg, 1); if (mpz_cmp(r,ghalf) > 0) // r > ghalf { mpz_sub(r,r,gg); mpz_add_ui(q,q,1); } if (gsign < 0) mpz_neg(q,q); mpz_clear(gg); mpz_clear(ghalf); quot = ring_elem(q); return ring_elem(r); }
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) ; }
static Variant HHVM_FUNCTION(gmp_div_qr, const Variant& dataA, const Variant& dataB, int64_t round = GMP_ROUND_ZERO) { mpz_t gmpDataA, gmpDataB, gmpReturnQ, gmpReturnR; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_QR, gmpDataB, dataB)) { mpz_clear(gmpDataA); return false; } if (mpz_sgn(gmpDataB) == 0) { mpz_clear(gmpDataA); mpz_clear(gmpDataB); raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO, cs_GMP_FUNC_NAME_GMP_DIV_QR); return false; } mpz_init(gmpReturnQ); mpz_init(gmpReturnR); switch (round) { case GMP_ROUND_ZERO: mpz_tdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB); break; case GMP_ROUND_PLUSINF: mpz_cdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB); break; case GMP_ROUND_MINUSINF: mpz_fdiv_qr(gmpReturnQ, gmpReturnR, gmpDataA, gmpDataB); break; default: mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturnQ); mpz_clear(gmpReturnR); return null_variant; } ArrayInit returnArray(2, ArrayInit::Map{}); returnArray.set(0, NEWOBJ(GMPResource)(gmpReturnQ)); returnArray.set(1, NEWOBJ(GMPResource)(gmpReturnR)); mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturnQ); mpz_clear(gmpReturnR); return returnArray.toVariant(); }
cl_object _ecl_big_floor(cl_object a, cl_object b, cl_object *pr) { cl_object q = _ecl_big_register0(); cl_object r = _ecl_big_register1(); mpz_fdiv_qr(q->big.big_num, r->big.big_num, a->big.big_num, b->big.big_num); *pr = _ecl_big_register_normalize(r); return _ecl_big_register_normalize(q); }
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); }
static int sdiv_qr (mpz_t q, mpz_t r, mp_size_t s, const mpz_t a, const mpz_t b) { mpz_fdiv_qr (q, r, a, b); if (mpz_size (r) <= s) { mpz_add (r, r, b); mpz_sub_ui (q, q, 1); } return (mpz_sgn (q) > 0); }
void encode(int* array, header h, int level) { int allzeroes = 1; if (level == LEVELS || h.size == 1) { return encode_last(array, h); } int counter = 0; int index = 0; int new_array[headers[level+1].size]; char* total = malloc(sizeof(char)*h.size); if(total == NULL) { printf("ERROR!\n"); exit(1); } char* start = total; while(counter < h.size) { if(h.size - counter < h.chunksize) { for(int i = 0; i < h.chunksize - h.size + counter; i++) total++; int tot = h.size - counter; for (int i = 0; i < tot; i++) { total[i] = array[counter] + '0'; counter++; } } else { for (int i = 0; i < h.chunksize; i++) { total[i] = array[counter] + '0'; counter++; } } mpz_set_str(number, total, h.K); mpz_fdiv_qr(k,m,number,divisor); if(mpz_sgn(k)) allzeroes = 0; new_array[index] = mpz_get_ui(k); unsigned int remains = mpz_get_ui(m); fwrite(&remains, sizeof(unsigned int), 1, output); index++; } free(start); if (allzeroes) return; return encode(new_array, headers[level+1], level + 1); }
// ----------------------------------------------------------------------------- // Calculate a compressed Rabin signature (see Compressing Rabin Signatures, // Daniel Bleichenbacher) // // zsig: (output) the resulting signature // s: the Rabin signature // n: the composite group order // ----------------------------------------------------------------------------- static void signature_compress(mpz_t zsig, mpz_t s, mpz_t n) { mpz_t vs[4]; mpz_init_set_ui(vs[0], 0); mpz_init_set_ui(vs[1], 1); mpz_init(vs[2]); mpz_init(vs[3]); mpz_t root; mpz_init(root); mpz_sqrt(root, n); mpz_t cf; mpz_init(cf); unsigned i = 1; do { i = (i + 1) & 3; if (i & 1) { mpz_fdiv_qr(cf, s, s, n); } else { mpz_fdiv_qr(cf, n, n, s); } mpz_mul(vs[i], vs[(i-1)&3], cf); mpz_add(vs[i], vs[i], vs[(i-2)&3]); } while (mpz_cmp(vs[i], root) < 0); mpz_init(zsig); mpz_set(zsig, vs[(i-1) & 3]); mpz_clear(root); mpz_clear(cf); mpz_clear(vs[0]); mpz_clear(vs[1]); mpz_clear(vs[2]); mpz_clear(vs[3]); }
static PyObject * GMPy_MPZ_Method_Round(PyObject *self, PyObject *args) { Py_ssize_t round_digits; MPZ_Object *result; mpz_t temp, rem; if (PyTuple_GET_SIZE(args) == 0) { Py_INCREF(self); return self; } round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } if (round_digits >= 0) { Py_INCREF(self); return self; } round_digits = -round_digits; if ((result = GMPy_MPZ_New(NULL))) { if (round_digits >= mpz_sizeinbase(MPZ(self), 10)) { mpz_set_ui(result->z, 0); } else { mpz_inoc(temp); mpz_inoc(rem); mpz_ui_pow_ui(temp, 10, round_digits); mpz_fdiv_qr(result->z, rem, MPZ(self), temp); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, temp) > 0) { mpz_add_ui(result->z, result->z, 1); } else if (mpz_cmp(rem, temp) == 0) { if (mpz_odd_p(result->z)) { mpz_add_ui(result->z, result->z, 1); } } mpz_mul(result->z, result->z, temp); mpz_cloc(rem); mpz_cloc(temp); } } return (PyObject*)result; }
/* uint64_t *factors_exp; /* this can be used to keep track for the full factorization of * an element x²-n. For the use of this version, refer to the * qs_exponent_vector.c version */ mpz_t factors_vect; /* this nb_primes_in_base bit vector is a substitute of the * factors_exp array, all we actually need for the elimination * in the Linear algebra step is the exponents modulo 2. * This saves huge space within the sieving step */ } smooth_number_t; mpz_t N; /* number to factorize */ matrix_t matrix; uint64_t nb_smooth_numbers_found = 0; uint64_t nb_qr_primes; /* number of primes p where N is a quadratic residue mod p */ uint64_t *primes; /* array holding the primes of the smoothness base */ smooth_number_t *smooth_numbers; int NB_VECTORS_OFFSET = 5; /* number of additional rows in the matrix, to make sure that a linear relation exists */ //----------------------------------------------------------- // base <- exp((1/2) sqrt(ln(n) ln(ln(n)))) //----------------------------------------------------------- void get_smoothness_base(mpz_t base, mpz_t n) { mpfr_t fN, lnN, lnlnN; mpfr_init(fN), mpfr_init(lnN), mpfr_init(lnlnN); mpfr_set_z(fN, n, MPFR_RNDU); mpfr_log(lnN, fN, MPFR_RNDU); mpfr_log(lnlnN, lnN, MPFR_RNDU); mpfr_mul(fN, lnN, lnlnN, MPFR_RNDU); mpfr_sqrt(fN, fN, MPFR_RNDU); mpfr_div_ui(fN, fN, 2, MPFR_RNDU); mpfr_exp(fN, fN, MPFR_RNDU); mpfr_get_z(base, fN, MPFR_RNDU); mpfr_clears(fN, lnN, lnlnN, NULL); } // returns the index of the first element to start sieving from // (first multiple of root that is directly greater than start) // res = p*t + root >= start */ void get_sieving_start_index(mpz_t res, mpz_t start, mpz_t p, unsigned long root) { mpz_t q, r; mpz_init(q); mpz_init(r); mpz_sub_ui(start, start, root); mpz_fdiv_qr(q, r, start, p); if (mpz_cmp_ui(r, 0) != 0) mpz_add_ui(q, q, 1); mpz_mul(q, q, p); /* next element p*q+root that is directly >= start */ mpz_add_ui(q, q, root); mpz_set(res, q); mpz_clear(q); mpz_clear(r); }
static int extract_digit() { if (mpz_cmp(numer, accum) > 0) return -1; /* Compute (numer * 3 + accum) / denom */ mpz_mul_2exp(tmp1, numer, 1); mpz_add(tmp1, tmp1, numer); mpz_add(tmp1, tmp1, accum); mpz_fdiv_qr(tmp1, tmp2, tmp1, denom); /* Now, if (numer * 4 + accum) % denom... */ mpz_add(tmp2, tmp2, numer); /* ... is normalized, then the two divisions have the same result. */ if (mpz_cmp(tmp2, denom) >= 0) return -1; return mpz_get_ui(tmp1); }
//~ Initialises remainning data of 'op' void init_glvRData(SGLVData *op){ mpz_t u, v, x1, x2, y1, y2, q, r, x, y, tmp; mpz_inits (u, v, x1, x2, y1, y2, q, r, x, y, tmp, NULL); mpz_set (u, op->efp); mpz_set (v, op->phi); mpz_set_ui (x1, 1); mpz_set_ui (y2, 1); while(mpz_cmp(u, op->refp) > 0){ mpz_fdiv_qr (q, r, v, u); mpz_mul (tmp, q, x1); mpz_sub (x, x2, tmp); mpz_mul (tmp, q, y1); mpz_sub (y, y2, tmp); mpz_set (v, u); mpz_set (u, r); mpz_set (x2, x1); mpz_set (x1, x); mpz_set (y2, y1); mpz_set (y1, y); } mpz_add (op->aa, u, y); // aa = u + y mpz_neg (op->bb, y); // bb = -y mpz_mul (x1, op->bb, op->bb); // x1 = (bb)^2 mpz_mul (x2, u, op->bb); // x2 = u * bb mpz_mul (op->Na, u, u); // Na = u^2 mpz_add (op->Na, op->Na, x1); // Na = u^2 + (bb)^2 mpz_sub (op->Na, op->Na, x2); // Na = u^2 + (bb)^2 - (u * bb) mpz_clears (u, v, x1, x2, y1, y2, q, r, x, y, tmp, NULL); }
void fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(h)) { printf("Exception: division by zero in fmpz_fdiv_q\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* h is also small */ { fmpz q = c1 / c2; /* compute C quotient */ fmpz r = c1 - c2 * q; /* compute remainder */ if ((c2 > 0L && r < 0L) || (c2 < 0L && r > 0L)) { q--; /* q cannot overflow as remainder implies |c2| != 1 */ r += c2; } fmpz_set_si(f, q); fmpz_set_si(s, r); } else /* h is large and g is small */ { if (c1 == 0L) { fmpz_set_ui(f, 0L); /* g is zero */ fmpz_set_si(s, c1); } else if ((c1 < 0L && fmpz_sgn(h) < 0) || (c1 > 0L && fmpz_sgn(h) > 0)) /* signs are the same */ { fmpz_zero(f); /* quotient is positive, round down to zero */ fmpz_set_si(s, c1); } else { fmpz_add(s, g, h); fmpz_set_si(f, -1L); /* quotient is negative, round down to minus one */ } } } else /* g is large */ { __mpz_struct *mpz_ptr, *mpz_ptr2; _fmpz_promote(f); /* must not hang on to ptr whilst promoting s */ mpz_ptr2 = _fmpz_promote(s); mpz_ptr = COEFF_TO_PTR(*f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { mpz_fdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2); } else { mpz_cdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2); mpz_neg(mpz_ptr, mpz_ptr); } } else /* both are large */ { mpz_fdiv_qr(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); } _fmpz_demote_val(f); /* division by h may result in small value */ _fmpz_demote_val(s); /* division by h may result in small value */ } }
void hex_random_op4 (enum hex_random_op op, unsigned long maxbits, char **ap, char **bp, char **cp, char **dp) { mpz_t a, b, c, d; unsigned long abits, bbits; unsigned signs; mpz_init (a); mpz_init (b); mpz_init (c); mpz_init (d); if (op == OP_POWM) { unsigned long cbits; abits = gmp_urandomb_ui (state, 32) % maxbits; bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits; mpz_rrandomb (a, state, abits); mpz_rrandomb (b, state, bbits); mpz_rrandomb (c, state, cbits); signs = gmp_urandomb_ui (state, 3); if (signs & 1) mpz_neg (a, a); if (signs & 2) { mpz_t g; /* If we negate the exponent, must make sure that gcd(a, c) = 1 */ if (mpz_sgn (a) == 0) mpz_set_ui (a, 1); else { mpz_init (g); for (;;) { mpz_gcd (g, a, c); if (mpz_cmp_ui (g, 1) == 0) break; mpz_divexact (a, a, g); } mpz_clear (g); } mpz_neg (b, b); } if (signs & 4) mpz_neg (c, c); mpz_powm (d, a, b, c); } else { unsigned long qbits; bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; qbits = gmp_urandomb_ui (state, 32) % maxbits; abits = bbits + qbits; if (abits > 30) abits -= 30; else abits = 0; mpz_rrandomb (a, state, abits); mpz_rrandomb (b, state, bbits); signs = gmp_urandomb_ui (state, 2); if (signs & 1) mpz_neg (a, a); if (signs & 2) mpz_neg (b, b); switch (op) { default: abort (); case OP_CDIV: mpz_cdiv_qr (c, d, a, b); break; case OP_FDIV: mpz_fdiv_qr (c, d, a, b); break; case OP_TDIV: mpz_tdiv_qr (c, d, a, b); break; } } gmp_asprintf (ap, "%Zx", a); gmp_asprintf (bp, "%Zx", b); gmp_asprintf (cp, "%Zx", c); gmp_asprintf (dp, "%Zx", d); mpz_clear (a); mpz_clear (b); mpz_clear (c); mpz_clear (d); }
value largeint_fdivmod(value quotdest, value remdest, value li1, value li2) { mpz_fdiv_qr(Large_val(quotdest), Large_val(remdest), Large_val(li1), Large_val(li2)); return Val_unit; }
void genNextLevelPrime(mpz_t prime, mpz_t r, mpz_t s, size_t length, gmp_randstate_t rand_state) { size_t k; mpz_t sinv; /* s^(-1) - inverse of s (mod r) */ mpz_t pow; /* 2^(n-1) */ mpz_t dprod; /* 2rs */ mpz_t Q; /* [pow / dprod] - integer part */ mpz_t R; /* remainder of pow/dprod */ mpz_t cond; /* temporary variable for 2*s*s^(-1) - 1 to check condition */ mpz_t Po; /* Po = 2*s*s^(-1) - 1 + Q*2rs, if 2*s*s^(-1) - 1 > R */ /* Po = 2*s*s^(-1) - 1 + (Q+1)*2rs, if 2*s*s^(-1) - 1 < R*/ mpz_init(prime); mpz_init(sinv); mpz_init(pow); mpz_init(dprod); mpz_init(Q); mpz_init(R); mpz_init(cond); mpz_init(Po); inverse(sinv, s, r); mpz_ui_pow_ui(pow, 2, length-1); /* find product 2rs */ mpz_mul_ui(dprod, r, 2); mpz_mul(dprod, dprod, s); /* compute Q and R */ mpz_fdiv_qr(Q, R, pow, dprod); /* compute 2*s*s^(-1) - 1 for condition check */ mpz_mul_ui(cond, s, 2); mpz_mul(cond, cond, sinv); mpz_sub_ui(cond, cond, 1); if(mpz_cmp(cond, R) > 0) { mpz_mul(Po, Q, dprod); mpz_add(Po, Po, cond); } else /* cond < R */ { mpz_add_ui(Q, Q, 1); mpz_mul(Po, Q, dprod); mpz_add(Po, Po, cond); } /* TODO: fix the magic number and use 2k < 2^t limit */ for(k = 0; k < 0.35*(length-1); ++k) { mpz_mul_ui(prime, dprod, k); mpz_add(prime, prime, Po); /* exit loop if the number is definately prime (return value is 2) */ if(mpz_probab_prime_p(prime, 40)) break; } mpz_clear(sinv); mpz_clear(pow); mpz_clear(dprod); mpz_clear(Q); mpz_clear(R); mpz_clear(cond); mpz_clear(Po); }
/*-------------------------------------------------------------------------*/ static int pol_expand(curr_poly_t *c, mpz_t gmp_N) { /* compute coefficients */ mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[5]); mpz_sub(c->gmp_help3, gmp_N, c->gmp_help4); mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p); if (mpz_sgn(c->gmp_help1)) return 0; if (mpz_cmp_ui(c->gmp_p, 1) == 0) mpz_set_ui(c->gmp_help2, 1); else { if (!mpz_invert(c->gmp_help2, c->gmp_d, c->gmp_p)) return 0; } mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3); mpz_fdiv_r(c->gmp_a[4], c->gmp_help4, c->gmp_p); mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help4); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[4]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4); mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p); if (mpz_sgn(c->gmp_help1)) return 0; mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d); mpz_fdiv_q(c->gmp_a[3], c->gmp_help3, c->gmp_help4); mpz_fdiv_q(c->gmp_a[3], c->gmp_a[3], c->gmp_p); mpz_mul(c->gmp_a[3], c->gmp_a[3], c->gmp_p); mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help2); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3); mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p); mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1); mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[3]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4); mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p); if (mpz_sgn(c->gmp_help1)) return 0; mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_fdiv_q(c->gmp_a[2], c->gmp_help3, c->gmp_help4); mpz_fdiv_q(c->gmp_a[2], c->gmp_a[2], c->gmp_p); mpz_mul(c->gmp_a[2], c->gmp_a[2], c->gmp_p); mpz_mul(c->gmp_help4, c->gmp_help2, c->gmp_help2); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_help3); mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p); mpz_add(c->gmp_a[2], c->gmp_a[2], c->gmp_help1); mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_d); mpz_mul(c->gmp_help4, c->gmp_help4, c->gmp_a[2]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4); mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p); if (mpz_sgn(c->gmp_help1)) return 0; mpz_fdiv_q(c->gmp_a[1], c->gmp_help3, c->gmp_d); mpz_fdiv_q(c->gmp_a[1], c->gmp_a[1], c->gmp_p); mpz_mul(c->gmp_a[1], c->gmp_a[1], c->gmp_p); mpz_mul(c->gmp_help4, c->gmp_help3, c->gmp_help2); mpz_fdiv_r(c->gmp_help1, c->gmp_help4, c->gmp_p); mpz_add(c->gmp_a[1], c->gmp_a[1], c->gmp_help1); mpz_mul(c->gmp_help4, c->gmp_d, c->gmp_a[1]); mpz_sub(c->gmp_help3, c->gmp_help3, c->gmp_help4); mpz_fdiv_qr(c->gmp_help3, c->gmp_help1, c->gmp_help3, c->gmp_p); if (mpz_sgn(c->gmp_help1)) return 0; mpz_set(c->gmp_a[0], c->gmp_help3); mpz_fdiv_qr(c->gmp_help1, c->gmp_a[3], c->gmp_a[3], c->gmp_d); mpz_add(c->gmp_help2, c->gmp_a[3], c->gmp_a[3]); if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) { mpz_sub(c->gmp_a[3], c->gmp_a[3], c->gmp_d); mpz_add_ui(c->gmp_help1, c->gmp_help1, 1); } mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p); mpz_add(c->gmp_a[4], c->gmp_a[4], c->gmp_help1); mpz_fdiv_qr(c->gmp_help1, c->gmp_a[2], c->gmp_a[2], c->gmp_d); mpz_add(c->gmp_help2, c->gmp_a[2], c->gmp_a[2]); if (mpz_cmp(c->gmp_d, c->gmp_help2) < 0) { mpz_sub(c->gmp_a[2], c->gmp_a[2], c->gmp_d); mpz_add_ui(c->gmp_help1, c->gmp_help1, 1); } mpz_mul(c->gmp_help1, c->gmp_help1, c->gmp_p); mpz_add(c->gmp_a[3], c->gmp_a[3], c->gmp_help1); mpz_set(c->gmp_lina[1], c->gmp_p); mpz_neg(c->gmp_lina[0], c->gmp_d); mpz_invert(c->gmp_m, c->gmp_p, gmp_N); mpz_mul(c->gmp_m, c->gmp_m, c->gmp_d); mpz_mod(c->gmp_m, c->gmp_m, gmp_N); if (verbose > 2) { int i; printf("pol-expand\npol0: "); for (i = 5; i >= 0; i--) { mpz_out_str(stdout, 10, c->gmp_a[i]); printf(" "); } printf("\npol1: "); mpz_out_str(stdout, 10, c->gmp_lina[1]); printf(" "); mpz_out_str(stdout, 10, c->gmp_lina[0]); printf("\n\n"); } return 1; }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("fdiv_qr...."); fflush(stdout); for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c, r; mpz_t d, e, f, g, h, s; slong j; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(r); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); mpz_init(h); mpz_init(s); fmpz_randbits(a, state, 1000); do { fmpz_randbits(b, state, 500); } while(fmpz_is_zero(b)); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); for (j = 1; j < 100; j++) fmpz_fdiv_qr(c, r, a, b); mpz_fdiv_qr(f, s, d, e); fmpz_get_mpz(g, c); fmpz_get_mpz(h, r); result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, e, f, g, h, s); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(r); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); mpz_clear(h); mpz_clear(s); } /* Check aliasing of c and a */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c, r; mpz_t d, e, f, g, h, s; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(r); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); mpz_init(h); mpz_init(s); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_fdiv_qr(a, r, a, b); mpz_fdiv_qr(f, s, d, e); fmpz_get_mpz(g, a); fmpz_get_mpz(h, r); result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, e, f, g, h, s); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(r); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); mpz_clear(h); mpz_clear(s); } /* Check aliasing of c and b */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c, r; mpz_t d, e, f, g, h, s; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(r); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); mpz_init(h); mpz_init(s); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_fdiv_qr(b, r, a, b); mpz_fdiv_qr(f, s, d, e); fmpz_get_mpz(g, b); fmpz_get_mpz(h, r); result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, e, f, g, h, s); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(r); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); mpz_clear(h); mpz_clear(s); } /* Check aliasing of r and a */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c, r; mpz_t d, e, f, g, h, s; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(r); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); mpz_init(h); mpz_init(s); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_fdiv_qr(c, a, a, b); mpz_fdiv_qr(f, s, d, e); fmpz_get_mpz(g, c); fmpz_get_mpz(h, a); result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, e, f, g, h, s); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(r); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); mpz_clear(h); mpz_clear(s); } /* Check aliasing of r and b */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c, r; mpz_t d, e, f, g, h, s; fmpz_init(a); fmpz_init(b); fmpz_init(c); fmpz_init(r); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); mpz_init(h); mpz_init(s); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_fdiv_qr(c, b, a, b); mpz_fdiv_qr(f, s, d, e); fmpz_get_mpz(g, c); fmpz_get_mpz(h, b); result = (mpz_cmp(f, g) == 0 && mpz_cmp(h, s) == 0); if (!result) { flint_printf("FAIL:\n"); gmp_printf ("d = %Zd, e = %Zd, f = %Zd, g = %Zd, h = %Zd, s = %Zd\n", d, e, f, g, h, s); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); fmpz_clear(r); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); mpz_clear(h); mpz_clear(s); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
RCP<const Basic> pow(const RCP<const Basic> &a, const RCP<const Basic> &b) { if (eq(b, zero)) return one; if (eq(b, one)) return a; if (eq(a, zero)) return zero; if (eq(a, one)) return one; if (eq(a, minus_one)) { if (is_a<Integer>(*b)) { return is_a<Integer>(*div(b, integer(2))) ? one : minus_one; } else if (is_a<Rational>(*b) && (rcp_static_cast<const Rational>(b)->i.get_num() == 1) && (rcp_static_cast<const Rational>(b)->i.get_den() == 2)) { return I; } } if (is_a_Number(*a) && is_a_Number(*b)) { if (is_a<Integer>(*b)) { if (is_a<Rational>(*a)) { RCP<const Rational> exp_new = rcp_static_cast<const Rational>(a); return exp_new->powrat(*rcp_static_cast<const Integer>(b)); } else if (is_a<Integer>(*a)) { RCP<const Integer> exp_new = rcp_static_cast<const Integer>(a); return exp_new->powint(*rcp_static_cast<const Integer>(b)); } else if (is_a<Complex>(*a)) { RCP<const Complex> exp_new = rcp_static_cast<const Complex>(a); RCP<const Integer> pow_new = rcp_static_cast<const Integer>(b); RCP<const Number> res = exp_new->pow(*pow_new); return res; } else { throw std::runtime_error("Not implemented"); } } else if (is_a<Rational>(*b)) { mpz_class q, r, num, den; num = rcp_static_cast<const Rational>(b)->i.get_num(); den = rcp_static_cast<const Rational>(b)->i.get_den(); if (num > den || num < 0) { mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(), den.get_mpz_t()); } else { return rcp(new Pow(a, b)); } // Here we make the exponent postive and a fraction between // 0 and 1. We multiply numerator and denominator appropriately // to achieve this if (is_a<Rational>(*a)) { RCP<const Rational> exp_new = rcp_static_cast<const Rational>(a); RCP<const Basic> frac = div(exp_new->powrat(Integer(q)), integer(exp_new->i.get_den())); RCP<const Basic> surds = mul(rcp(new Pow(integer(exp_new->i.get_num()), div(integer(r), integer(den)))), rcp(new Pow(integer(exp_new->i.get_den()), sub(one, div(integer(r), integer(den)))))); return mul(frac, surds); } else if (is_a<Integer>(*a)) { RCP<const Integer> exp_new = rcp_static_cast<const Integer>(a); RCP<const Number> frac = exp_new->powint(Integer(q)); map_basic_basic surd; if ((exp_new->is_negative()) && (2 * r == den)) { frac = mulnum(frac, I); exp_new = exp_new->mulint(*minus_one); // if exp_new is one, no need to add it to dict if (exp_new->is_one()) return frac; surd[exp_new] = div(integer(r), integer(den)); } else { surd[exp_new] = div(integer(r), integer(den)); } return rcp(new Mul(frac, std::move(surd))); } else if (is_a<Complex>(*a)) { return rcp(new Pow(a, b)); } else { throw std::runtime_error("Not implemented"); } } else if (is_a<Complex>(*b)) { return rcp(new Pow(a, b)); } else { throw std::runtime_error("Not implemented"); } } if (is_a<Mul>(*a) && is_a<Integer>(*b)) { // Convert (x*y)^b = x^b*y^b, where 'b' is an integer. This holds for // any complex 'x', 'y' and integer 'b'. return rcp_static_cast<const Mul>(a)->power_all_terms(b); } if (is_a<Pow>(*a) && is_a<Integer>(*b)) { // Convert (x^y)^b = x^(b*y), where 'b' is an integer. This holds for // any complex 'x', 'y' and integer 'b'. RCP<const Pow> A = rcp_static_cast<const Pow>(a); return pow(A->base_, mul(A->exp_, b)); } return rcp(new Pow(a, b)); }
static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result; MPZ_Object *tempx, *tempy, *rem, *quo; mpz_t tempz; long temp; int error; result = PyTuple_New(2); rem = GMPy_MPZ_New(context); quo = GMPy_MPZ_New(context); if (!result || !rem || !quo) { Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; } if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { temp = GMPy_Integer_AsLongAndError(y, &error); if (error) { mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz); mpz_cloc(tempz); } else if (temp > 0) { mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } else { mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp); mpz_neg(quo->z, quo->z); } PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y)); mpz_cloc(tempz); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } if (IS_INTEGER(x) && IS_INTEGER(y)) { tempx = GMPy_MPZ_From_Integer(x, context); tempy = GMPy_MPZ_From_Integer(y, context); if (!tempx || !tempy) { SYSTEM_ERROR("could not convert Integer to mpz"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)rem); Py_DECREF((PyObject*)quo); Py_DECREF(result); return NULL; } mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } Py_DECREF((PyObject*)result); Py_RETURN_NOTIMPLEMENTED; }
static int mpfr_rem1 (mpfr_ptr rem, long *quo, mp_rnd_t rnd_q, mpfr_srcptr x, mpfr_srcptr y, mp_rnd_t rnd) { mp_exp_t ex, ey; int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x); mpz_t mx, my, r; MPFR_ASSERTD (rnd_q == GMP_RNDN || rnd_q == GMP_RNDZ); if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y))) { if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x) || MPFR_IS_ZERO (y)) { /* for remquo, quo is undefined */ MPFR_SET_NAN (rem); MPFR_RET_NAN; } else /* either y is Inf and x is 0 or non-special, or x is 0 and y is non-special, in both cases the quotient is zero. */ { if (quo) *quo = 0; return mpfr_set (rem, x, rnd); } } /* now neither x nor y is NaN, Inf or zero */ mpz_init (mx); mpz_init (my); mpz_init (r); ex = mpfr_get_z_exp (mx, x); /* x = mx*2^ex */ ey = mpfr_get_z_exp (my, y); /* y = my*2^ey */ /* to get rid of sign problems, we compute it separately: quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y) quo(-x,y) = -quo(x,y), rem(-x,y) = -rem(x,y) thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */ sign = (signx == MPFR_SIGN (y)) ? 1 : -1; mpz_abs (mx, mx); mpz_abs (my, my); q_is_odd = 0; /* divide my by 2^k if possible to make operations mod my easier */ { unsigned long k = mpz_scan1 (my, 0); ey += k; mpz_div_2exp (my, my, k); } if (ex <= ey) { /* q = x/y = mx/(my*2^(ey-ex)) */ mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */ if (rnd_q == GMP_RNDZ) /* 0 <= |r| <= |my|, r has the same sign as mx */ mpz_tdiv_qr (mx, r, mx, my); else /* 0 <= |r| <= |my|, r has the same sign as my */ mpz_fdiv_qr (mx, r, mx, my); if (rnd_q == GMP_RNDN) q_is_odd = mpz_tstbit (mx, 0); if (quo) /* mx is the quotient */ { mpz_tdiv_r_2exp (mx, mx, WANTED_BITS); *quo = mpz_get_si (mx); } } else /* ex > ey */ { if (quo) /* for remquo, to get the low WANTED_BITS more bits of the quotient, we first compute R = X mod Y*2^WANTED_BITS, where X and Y are defined below. Then the low WANTED_BITS of the quotient are floor(R/Y). */ mpz_mul_2exp (my, my, WANTED_BITS); /* 2^WANTED_BITS*Y */ else /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers. Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y). To be able to perform the rounding, we need the least significant bit of the quotient, i.e., one more bit in the remainder, which is obtained by dividing by 2Y. */ mpz_mul_2exp (my, my, 1); /* 2Y */ mpz_set_ui (r, 2); mpz_powm_ui (r, r, ex - ey, my); /* 2^(ex-ey) mod my */ mpz_mul (r, r, mx); mpz_mod (r, r, my); if (quo) /* now 0 <= r < 2^WANTED_BITS*Y */ { mpz_div_2exp (my, my, WANTED_BITS); /* back to Y */ mpz_tdiv_qr (mx, r, r, my); /* oldr = mx*my + newr */ *quo = mpz_get_si (mx); q_is_odd = *quo & 1; } else /* now 0 <= r < 2Y */ { mpz_div_2exp (my, my, 1); /* back to Y */ if (rnd_q == GMP_RNDN) { /* least significant bit of q */ q_is_odd = mpz_cmpabs (r, my) >= 0; if (q_is_odd) mpz_sub (r, r, my); } } /* now 0 <= |r| < |my|, and if needed, q_is_odd is the least significant bit of q */ } if (mpz_cmp_ui (r, 0) == 0) inex = mpfr_set_ui (rem, 0, GMP_RNDN); else { if (rnd_q == GMP_RNDN) { /* FIXME: the comparison 2*r < my could be done more efficiently at the mpn level */ mpz_mul_2exp (r, r, 1); compare = mpz_cmpabs (r, my); mpz_div_2exp (r, r, 1); compare = ((compare > 0) || ((rnd_q == GMP_RNDN) && (compare == 0) && q_is_odd)); /* if compare != 0, we need to subtract my to r, and add 1 to quo */ if (compare) { mpz_sub (r, r, my); if (quo && (rnd_q == GMP_RNDN)) *quo += 1; } } inex = mpfr_set_z (rem, r, rnd); /* if ex > ey, rem should be multiplied by 2^ey, else by 2^ex */ MPFR_EXP (rem) += (ex > ey) ? ey : ex; } if (quo) *quo *= sign; /* take into account sign of x */ if (signx < 0) { mpfr_neg (rem, rem, GMP_RNDN); inex = -inex; } mpz_clear (mx); mpz_clear (my); mpz_clear (r); return inex; }
// Mul (t**exp) to the dict "d" void Mul::dict_add_term_new(const Ptr<RCP<const Number>> &coef, map_basic_basic &d, const RCP<const Basic> &exp, const RCP<const Basic> &t) { auto it = d.find(t); if (it == d.end()) { // Don't check for `exp = 0` here // `pow` for Complex is not expanded by default if (is_a<Integer>(*t) || is_a<Rational>(*t)) { if (is_a<Integer>(*exp)) { imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(exp))); } else if (is_a<Rational>(*exp)) { // Here we make the exponent postive and a fraction between // 0 and 1. mpz_class q, r, num, den; num = rcp_static_cast<const Rational>(exp)->i.get_num(); den = rcp_static_cast<const Rational>(exp)->i.get_den(); mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(), den.get_mpz_t()); insert(d, t, Rational::from_mpq(mpq_class(r, den))); imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(integer(q)))); } else { insert(d, t, exp); } } else if (is_a<Integer>(*exp) && is_a<Complex>(*t)) { if (rcp_static_cast<const Integer>(exp)->is_one()) { imulnum(outArg(*coef), rcp_static_cast<const Number>(t)); } else if (rcp_static_cast<const Integer>(exp)->is_minus_one()) { idivnum(outArg(*coef), rcp_static_cast<const Number>(t)); } else { insert(d, t, exp); } } else { insert(d, t, exp); } } else { // Very common case, needs to be fast: if (is_a_Number(*exp) && is_a_Number(*it->second)) { RCP<const Number> tmp = rcp_static_cast<const Number>(it->second); iaddnum(outArg(tmp), rcp_static_cast<const Number>(exp)); it->second = tmp; } else it->second = add(it->second, exp); if (is_a<Integer>(*it->second)) { // `pow` for Complex is not expanded by default if (is_a<Integer>(*t) || is_a<Rational>(*t)) { if (!rcp_static_cast<const Integer>(it->second)->is_zero()) { imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(it->second))); } d.erase(it); } else if (rcp_static_cast<const Integer>(it->second)->is_zero()) { d.erase(it); } else if (is_a<Complex>(*t)) { if (rcp_static_cast<const Integer>(it->second)->is_one()) { imulnum(outArg(*coef), rcp_static_cast<const Number>(t)); d.erase(it); } else if (rcp_static_cast<const Integer>(it->second)->is_minus_one()) { idivnum(outArg(*coef), rcp_static_cast<const Number>(t)); d.erase(it); } } } else if (is_a<Rational>(*it->second)) { if (is_a_Number(*t)) { mpz_class q, r, num, den; num = rcp_static_cast<const Rational>(it->second)->i.get_num(); den = rcp_static_cast<const Rational>(it->second)->i.get_den(); // Here we make the exponent postive and a fraction between // 0 and 1. if (num > den || num < 0) { mpz_fdiv_qr(q.get_mpz_t(), r.get_mpz_t(), num.get_mpz_t(), den.get_mpz_t()); it->second = Rational::from_mpq(mpq_class(r, den)); imulnum(outArg(*coef), pownum(rcp_static_cast<const Number>(t), rcp_static_cast<const Number>(integer(q)))); } } } } }
void Serveur_xD(int dim, mpz_t ** tab_cli, mpz_t Answer[(int)pow(2, (dim - 1))], mpz_t * tab_serv) { int lenth_u_v = pow(MAX_GRID_SIZE, (dim - 1)); mpz_t * tab_u_v_1 = malloc(sizeof(mpz_t) * lenth_u_v); mpz_t * tab_u_v_2 = malloc(sizeof(mpz_t) * lenth_u_v); for (int i = 0; i < lenth_u_v; i++) { mpz_init(tab_u_v_1[i]); mpz_init(tab_u_v_2[i]); } mpz_t tab_tmp_1[MAX_GRID_SIZE]; mpz_t tab_tmp_2[MAX_GRID_SIZE]; for (int i = 0; i < MAX_GRID_SIZE; i++) { mpz_init(tab_tmp_1[i]); mpz_init(tab_tmp_2[i]); } int n_tab_cli = dim - 1; /* Part 1: First operation note to tab_u_v */ for (int i = 0; i < lenth_u_v; i++) { for (int j = 0; j < MAX_GRID_SIZE; j++) { mpz_set(tab_tmp_1[j], tab_serv[i * MAX_GRID_SIZE + j]); } // one line copy done from server /* compute every table with tab_cli and change to u and v*/ Serveur(tab_u_v_1[i], tab_tmp_1, tab_cli[n_tab_cli]); mpz_fdiv_qr (tab_u_v_1[i], tab_u_v_2[i], tab_u_v_1[i], KPub[0]); } /* Part 1 END */ /* Part 2: separation and compute circularly */ int count_position = 0; int count_uv = 0; for (int d = 1; d <= (dim - 2); d++) { n_tab_cli--; for (int i = 0; i < (lenth_u_v / (pow(2, (d - 1)))); i++) { if(count_position != (MAX_GRID_SIZE - 1)) { mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]); mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]); count_position++; } else { mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]); mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]); Serveur(tab_u_v_1[count_uv], tab_tmp_1, tab_cli[n_tab_cli]); Serveur(tab_u_v_2[count_uv], tab_tmp_2, tab_cli[n_tab_cli]); count_uv++; count_position = 0; } } /* Compute done */ for (int i = 0; i < (lenth_u_v / (d * MAX_GRID_SIZE)); i++) // { mpz_fdiv_qr (tab_u_v_1[i], tab_u_v_1[i + (lenth_u_v / (d * MAX_GRID_SIZE))], tab_u_v_1[i], KPub[0]); mpz_fdiv_qr (tab_u_v_2[i], tab_u_v_2[i + (lenth_u_v / (d * MAX_GRID_SIZE))], tab_u_v_2[i], KPub[0]); } } /* Part 2 END */ /* Part 3: Compute the value return to client */ count_position = 0; count_uv = 0; for (int i = 0; i < (MAX_GRID_SIZE * (pow(2, (dim - 2)))); i++) { if(count_position != (MAX_GRID_SIZE - 1)) { mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]); mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]); count_position++; } else { mpz_set(tab_tmp_1[count_position], tab_u_v_1[i]); mpz_set(tab_tmp_2[count_position], tab_u_v_2[i]); count_position = 0; Serveur(Answer[count_uv], tab_tmp_1, tab_cli[0]); Serveur(Answer[count_uv + (int)pow(2, (dim - 2))], tab_tmp_2, tab_cli[0]); if(count_uv < (pow(2, (dim - 2))) - 2) { count_uv+=2; } else { count_uv = 1; } } } /* Part 3 END */ for (int i = 0; i < MAX_GRID_SIZE; i++) { mpz_clear(tab_tmp_1[i]); mpz_clear(tab_tmp_2[i]); } for (int i = 0; i < lenth_u_v; i++) { mpz_clear(tab_u_v_1[i]); mpz_clear(tab_u_v_2[i]); } free(tab_u_v_1); free(tab_u_v_2); }
static PyObject * GMPy_Integer_DivMod(PyObject *x, PyObject *y, CTXT_Object *context) { PyObject *result = NULL; MPZ_Object *tempx = NULL, *tempy = NULL, *rem = NULL, *quo = NULL; if (!(result = PyTuple_New(2)) || !(rem = GMPy_MPZ_New(context)) || !(quo = GMPy_MPZ_New(context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (CHECK_MPZANY(x)) { if (PyIntOrLong_Check(y)) { int error; long temp = GMPy_Integer_AsLongAndError(y, &error); if (error) { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, y); mpz_fdiv_qr(quo->z, rem->z, MPZ(x), tempz); mpz_cloc(tempz); } else if (temp > 0) { mpz_fdiv_qr_ui(quo->z, rem->z, MPZ(x), temp); } else if (temp == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_cdiv_qr_ui(quo->z, rem->z, MPZ(x), -temp); mpz_neg(quo->z, quo->z); } PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } if (CHECK_MPZANY(y)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, MPZ(x), MPZ(y)); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } } if (CHECK_MPZANY(y) && PyIntOrLong_Check(x)) { if (mpz_sgn(MPZ(y)) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } else { mpz_t tempz; mpz_inoc(tempz); mpz_set_PyIntOrLong(tempz, x); mpz_fdiv_qr(quo->z, rem->z, tempz, MPZ(y)); mpz_cloc(tempz); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return (PyObject*)result; } } if (IS_INTEGER(x) && IS_INTEGER(y)) { if (!(tempx = GMPy_MPZ_From_Integer(x, context)) || !(tempy = GMPy_MPZ_From_Integer(y, context))) { /* LCOV_EXCL_START */ goto error; /* LCOV_EXCL_STOP */ } if (mpz_sgn(tempy->z) == 0) { ZERO_ERROR("division or modulo by zero"); goto error; } mpz_fdiv_qr(quo->z, rem->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); PyTuple_SET_ITEM(result, 0, (PyObject*)quo); PyTuple_SET_ITEM(result, 1, (PyObject*)rem); return result; } /* LCOV_EXCL_START */ SYSTEM_ERROR("Internal error in GMPy_Integer_DivMod()."); /* LCOV_EXCL_STOP */ error: Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_XDECREF((PyObject*)rem); Py_XDECREF((PyObject*)quo); Py_XDECREF(result); return NULL; }
static PyObject * Pympq_round(PyObject *self, PyObject *args) { Py_ssize_t round_digits = 0; PympqObject *resultq; PympzObject *resultz; mpz_t temp, rem; /* If args is NULL or the size of args is 0, we just return an mpz. */ if (!args || PyTuple_GET_SIZE(args) == 0) { if (!(resultz = (PympzObject*)Pympz_new())) return NULL; mpz_inoc(rem); mpz_fdiv_qr(resultz->z, rem, mpq_numref(Pympq_AS_MPQ(self)), mpq_denref(Pympq_AS_MPQ(self))); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) > 0) { mpz_add_ui(resultz->z, resultz->z, 1); } else if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) == 0) { if (mpz_odd_p(resultz->z)) { mpz_add_ui(resultz->z, resultz->z, 1); } } mpz_cloc(rem); return (PyObject*)resultz; } if (PyTuple_GET_SIZE(args) > 1) { TYPE_ERROR("Too many arguments for __round__()."); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } } if (!(resultq = (PympqObject*)Pympq_new())) return NULL; mpz_inoc(temp); mpz_ui_pow_ui(temp, 10, round_digits > 0 ? round_digits : -round_digits); mpq_set(resultq->q, Pympq_AS_MPQ(self)); if (round_digits > 0) { mpz_mul(mpq_numref(resultq->q), mpq_numref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpz_set(mpq_numref(resultq->q), resultz->z); Py_DECREF((PyObject*)resultz); mpz_set(mpq_denref(resultq->q), temp); mpz_cloc(temp); mpq_canonicalize(resultq->q); } else { mpz_mul(mpq_denref(resultq->q), mpq_denref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpq_set_ui(resultq->q, 0, 1); mpz_mul(mpq_numref(resultq->q), resultz->z, temp); Py_DECREF((PyObject*)resultz); mpz_cloc(temp); mpq_canonicalize(resultq->q); } return (PyObject*)resultq; }