static void check_nan_inf_mpq (void) { mpfr_t mpfr_value, mpfr_cmp; mpq_t mpq_value; int status; mpfr_init2 (mpfr_value, MPFR_PREC_MIN); mpq_init (mpq_value); mpq_set_si (mpq_value, 0, 0); mpz_set_si (mpq_denref (mpq_value), 0); status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN); if ((status != 0) || (!MPFR_IS_NAN (mpfr_value))) { mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN); mpfr_set_nan (mpfr_cmp); printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n" " waiting for "); mpfr_print_binary (mpfr_cmp); printf (" got "); mpfr_print_binary (mpfr_value); printf ("\n trinary value is %d\n", status); exit (1); } mpq_set_si (mpq_value, -1, 0); mpz_set_si (mpq_denref (mpq_value), 0); status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN); if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) || (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value))) { mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN); mpfr_set_inf (mpfr_cmp, -1); printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n" " waiting for "); mpfr_print_binary (mpfr_cmp); printf (" got "); mpfr_print_binary (mpfr_value); printf ("\n trinary value is %d\n", status); exit (1); } mpq_clear (mpq_value); mpfr_clear (mpfr_value); }
void convert_to_z(mpz_t z, const mpq_t q, const mpz_t prime) { assert(mpz_sgn(prime) != 0); if (mpz_cmp_ui(mpq_denref(q), 1) == 0) { mpz_set(z, mpq_numref(q)); if (mpq_sgn(q) < 0) { mpz_mod(z, z, prime); } } else if (mpz_cmp_ui(mpq_denref(q), 0) == 0) { mpz_set_ui(z, 0); } else { mpz_invert(z, mpq_denref(q), prime); mpz_mul(z, z, mpq_numref(q)); mpz_mod(z, z, prime); } }
bool QQ::lower_associate_divisor(ring_elem &f, const ring_elem g) const { gmp_QQ a = MPQ_VAL(f); gmp_QQ b = MPQ_VAL(g); int sa = mpq_sgn(a); int sb = mpq_sgn(b); int s = (sa == 0 ? sb : sa); gmp_QQ result = QQ::new_elem(); mpz_gcd(mpq_numref(result), mpq_numref(a), mpq_numref(b)); mpz_lcm(mpq_denref(result), mpq_denref(a), mpq_denref(b)); if (s != mpq_sgn(result)) mpq_neg(result,result); f = MPQ_RINGELEM(result); return true; // the answer could become lower, if a newer g has a larger denom }
static PyObject * Pympq_sizeof(PyObject *self, PyObject *other) { return PyIntOrLong_FromSize_t(sizeof(PympqObject) + \ (mpq_numref(Pympq_AS_MPQ(self))->_mp_alloc * sizeof(mp_limb_t)) + \ (mpq_denref(Pympq_AS_MPQ(self))->_mp_alloc * sizeof(mp_limb_t))); }
void QQ::elem_text_out(buffer &o, const ring_elem ap, bool p_one, bool p_plus, bool p_parens) const { gmp_QQ a = MPQ_VAL(ap); char s[1000]; char *str; bool is_neg = (mpq_sgn(a) == -1); bool is_one = (mask_mpq_cmp_si(a, 1, 1) == 0 || mask_mpq_cmp_si(a, -1, 1) == 0); int size = static_cast<int>(mpz_sizeinbase (mpq_numref(a), 10) + mpz_sizeinbase (mpq_denref(a), 10) + 3); char *allocstr = (size > 1000 ? newarray_atomic(char,size) : s); if (!is_neg && p_plus) o << '+'; if (is_one) { if (is_neg) o << '-'; if (p_one) o << '1'; } else { str = mpq_get_str(allocstr, 10, a); o << str; } if (size > 1000) deletearray(allocstr); }
void fmpq_poly_scalar_div_mpq(fmpq_poly_t rop, const fmpq_poly_t op, const mpq_t c) { fmpz_t r, s; if (mpq_sgn(c) == 0) { printf("Exception: division by zero in fmpq_poly_scalar_div_mpq\n"); abort(); } if (fmpq_poly_is_zero(op)) { fmpq_poly_zero(rop); return; } fmpq_poly_fit_length(rop, op->length); _fmpq_poly_set_length(rop, op->length); fmpz_init(r); fmpz_init(s); fmpz_set_mpz(r, mpq_numref(c)); fmpz_set_mpz(s, mpq_denref(c)); _fmpq_poly_scalar_div_mpq(rop->coeffs, rop->den, op->coeffs, op->den, op->length, r, s); fmpz_clear(r); fmpz_clear(s); }
void check_data (void) { static const struct { int base; const char *num; const char *den; const char *want; } data[] = { { 10, "0", "1", "0" }, { 10, "1", "1", "1" }, { 16, "ffffffff", "1", "ffffffff" }, { 16, "ffffffffffffffff", "1", "ffffffffffffffff" }, { 16, "1", "ffffffff", "1/ffffffff" }, { 16, "1", "ffffffffffffffff", "1/ffffffffffffffff" }, { 16, "1", "10000000000000003", "1/10000000000000003" }, { 10, "12345678901234567890", "9876543210987654323", "12345678901234567890/9876543210987654323" }, }; mpq_t q; int i; mpq_init (q); for (i = 0; i < numberof (data); i++) { mpz_set_str_or_abort (mpq_numref(q), data[i].num, data[i].base); mpz_set_str_or_abort (mpq_denref(q), data[i].den, data[i].base); check_all (q, data[i].base, data[i].want); } mpq_clear (q); }
int promoteToMPZNumber(number *n) { switch(n->type) { case V_INTEGER: mpz_init_set_si64(n->value.mpz, n->value.i); n->type = V_MPZ; break; case V_MPZ: break; case V_MPQ: { mpz_t mpz; mpz_init(mpz); mpz_tdiv_q(mpz, mpq_numref(n->value.mpq), mpq_denref(n->value.mpq)); clearNumber(n); n->type = V_MPZ; n->value.mpz[0] = mpz[0]; break; } case V_FLOAT: mpz_init_set_d(n->value.mpz, n->value.f); n->type = V_MPZ; break; } return TRUE; }
void ARingGF::set_from_mpq(ElementType &result, const mpq_ptr a) const { // std::cerr << "set_from_mpq" << std::endl; ElementType n, d; set_from_mpz(n, mpq_numref(a)); set_from_mpz(d, mpq_denref(a)); divide(result,n,d); }
bool RingZZ::from_rational(mpq_ptr q, ring_elem &result) const { bool ok = mpz_cmp_si(mpq_denref(q), 1) == 0; if (not ok) return false; result = RingZZ::from_int(mpq_numref(q)); return true; }
obj string_to_rational_obj( char *str, unsigned radix ) { char *f; mpq_t b, w; f = strchr( str, '+' ); /* support WHOLE+NUM/DEN syntax */ if (f) { MP_INT *num; mpz_t numa; if (!str2rat( &b, f+1, radix )) { return FALSE_OBJ; } *f = '\0'; num = mpq_numref(w); if (!str2big( num, str, radix )) { *f = '+'; return FALSE_OBJ; } *f = '+'; mpz_init_set_si( mpq_denref(w), 1 ); mpq_add( b, b, w ); } else { if (!str2rat( &b, str, radix )) { return FALSE_OBJ; } } return rational_compact( b ); }
int promoteToMPQNumber(number *n) { switch(n->type) { case V_INTEGER: promoteToMPZNumber(n); /*FALLTHOURGH*/ case V_MPZ: { n->value.mpq->_mp_num = n->value.mpz[0]; mpz_init_set_ui(mpq_denref(n->value.mpq), 1L); n->type = V_MPQ; break; } case V_MPQ: break; case V_FLOAT: { double v = n->value.f; n->type = V_MPQ; mpq_init(n->value.mpq); mpq_set_d(n->value.mpq, v); break; } } return TRUE; }
void check_random (int argc, char **argv) { double d, d2, nd, dd; mpq_t q; mp_limb_t rp[LIMBS_PER_DOUBLE + 1]; int test, reps = 100000; int i; if (argc == 2) reps = 100 * atoi (argv[1]); mpq_init (q); for (test = 0; test < reps; test++) { mpn_random2 (rp, LIMBS_PER_DOUBLE + 1); d = 0.0; for (i = LIMBS_PER_DOUBLE - 1; i >= 0; i--) d = d * MP_BASE_AS_DOUBLE + rp[i]; d = my_ldexp (d, (int) (rp[LIMBS_PER_DOUBLE] % (2 * MAXEXP)) - MAXEXP); mpq_set_d (q, d); nd = mpz_get_d (mpq_numref (q)); dd = mpz_get_d (mpq_denref (q)); d2 = nd / dd; if (d != d2) { printf ("ERROR (check_random test %d): bad mpq_set_d results\n", test); printf ("%.16g\n", d); printf ("%.16g\n", d2); abort (); } } mpq_clear (q); }
/* * Store a value in a PP structure. * Input: * pp_pp* pp: pointer to the PP structure to store in * mpq_t value: the value to store * int parent: the parent to refer to * int self: TRUE if value represents 1/parent, FALSE if it represents the * resolution of pp[parent] * Returns: * Nothing. * Effect: * The specified value is stored in the specified PP structure, with a * reference to the specified parent. Internal variables are updated * accordingly. * * For a given value q, the caller is expected to have determined the * greatest prime power p^k dividing the denominator of q. In this case, * the pp structure should be that for p^k. * * The parent is used solely for determining a final solution vector. * If the value is a source value (i.e. 1/r representing the integer * r in the solution vector), the parent should be set to r, and self should * be TRUE. If not, the parent is assumed to be a fully resolved PP structure * storing a walk result that specifies the actual vector contribution * (possibly recursively), and self should be FALSE. */ void pp_save_any(pp_pp* pp, mpq_t value, int parent, int self) { int i; mpz_t zvalue; pp_value* v; ZINIT(&zvalue, "pp_save_any zvalue"); /* new value = mpq_numref(value) * (denominator / mpq_denref(value)) * new_pp() setting of denominator guarantees exactness */ mpz_divexact(zvalue, pp->denominator, mpq_denref(value)); mpz_mul(zvalue, zvalue, mpq_numref(value)); /* adding to total may change required fixed size, at worst once per pp */ mpz_add(pp->total, pp->total, zvalue); if (pp->total->_mp_size > pp->valnumsize) { Dprintf("pp_%d: growing to %d with total %Zd (denom %Zd)\n", pp->pp, pp->total->_mp_size, pp->total, pp->denominator); pp_grownum(pp, pp->total->_mp_size); } ++pp->valsize; pp_grow(pp, pp->valsize); v = pp_value_i(pp, pp->valsize - 1); v->parent = parent; v->self = self; v->inv = (pp->invdenom * mod_ui(zvalue, pp->p)) % pp->p; /* ref: MAX_P */ mpx_set_z(ppv_mpx(v), pp->valnumsize, zvalue); pp->invtotal = (pp->invtotal + v->inv) % pp->p; pp_insert_last(pp); ZCLEAR(&zvalue, "pp_save_any zvalue"); }
void mpq_set_si (MP_RAT *dest, signed long int num, unsigned long int den) { unsigned long int abs_num; if (GMP_NUMB_BITS < BITS_PER_ULONG) { if (num == 0) /* Canonicalize 0/d to 0/1. */ den = 1; mpz_set_si (mpq_numref (dest), num); mpz_set_ui (mpq_denref (dest), den); return; } abs_num = ABS_CAST (unsigned long, num); if (num == 0) { /* Canonicalize 0/d to 0/1. */ den = 1; dest->_mp_num._mp_size = 0; } else { dest->_mp_num._mp_d[0] = abs_num; dest->_mp_num._mp_size = num > 0 ? 1 : -1; } dest->_mp_den._mp_d[0] = den; dest->_mp_den._mp_size = (den != 0); }
/// @Mike: change all uses of set_from_mpq to return bool // or, perhaps, to raise an exception. void ARingZZpFFPACK::set_from_mpq(ElementType &result, const mpq_ptr a) const { ElementType n, d; set_from_mpz(n, mpq_numref(a)); set_from_mpz(d, mpq_denref(a)); divide(result, n, d); }
void mpq_set_ui (MP_RAT *dest, unsigned long int num, unsigned long int den) { if (GMP_NUMB_BITS < BITS_PER_ULONG) { if (num == 0) /* Canonicalize 0/d to 0/1. */ den = 1; mpz_set_ui (mpq_numref (dest), num); mpz_set_ui (mpq_denref (dest), den); return; } if (num == 0) { /* Canonicalize 0/n to 0/1. */ den = 1; SIZ(NUM(dest)) = 0; } else { PTR(NUM(dest))[0] = num; SIZ(NUM(dest)) = 1; } PTR(DEN(dest))[0] = den; SIZ(DEN(dest)) = (den != 0); }
ring_elem FractionField::from_rational(mpq_ptr n) const { frac_elem *f = new_frac_elem(); f->numer = R_->from_int(mpq_numref(n)); f->denom = R_->from_int(mpq_denref(n)); return FRAC_RINGELEM(f); }
static void e_mpq_num (mpq_ptr w, mpq_srcptr x) { if (w != x) mpz_set (mpq_numref(w), mpq_numref(x)); mpz_set_ui (mpq_denref(w), 1L); }
void mpq_set_si (mpq_ptr dest, mpir_si num, mpir_ui den) { mpir_ui abs_num; if (GMP_NUMB_BITS < BITS_PER_UI) { if (num == 0) /* Canonicalize 0/d to 0/1. */ den = 1; mpz_set_si (mpq_numref (dest), num); mpz_set_ui (mpq_denref (dest), den); return; } abs_num = ABS (num); if (num == 0) { /* Canonicalize 0/d to 0/1. */ den = 1; dest->_mp_num._mp_size = 0; } else { dest->_mp_num._mp_d[0] = abs_num; dest->_mp_num._mp_size = num > 0 ? 1 : -1; } dest->_mp_den._mp_d[0] = den; dest->_mp_den._mp_size = (den != 0); }
void set_from_mpq(elem &result, mpq_ptr a) const { elem n, d; set_from_mpz(n, mpq_numref(a)); set_from_mpz(d, mpq_denref(a)); ASSERT(d != 0); //TODO actually: we need to check for this... divide(result,n,d); }
//----------------------------------------------------------------------------- // utility functions //----------------------------------------------------------------------------- mpq_class MpqFromRational(const Rational &ratio) { mpq_t num; ::mpq_init(num); ::mpz_set_si(mpq_numref(num), ratio.numer); ::mpz_set_si(mpq_denref(num), ratio.denom); return mpq_class(num); }
bool lift_to_mpz(mpz_ptr result, const ElementType& a) const { if (mpz_cmp_si(mpq_denref(&a), 1) == 0) { mpz_set(result, mpq_numref(&a)); return true; } return false; }
void Lib_Mpq_Set_Si64(MpqPtr x, int64_t p) { mpz_set_si( mpq_numref((mpq_ptr) x), p); mpz_set_si( mpq_denref((mpq_ptr) x), 1); // Lib_Mpz_Set_Si64( mpq_numref((mpq_ptr) x), p); // Lib_Mpz_Set_Si( mpq_denref((mpq_ptr) x), 1); }
void dump (mpq_t x) { mpz_out_str (stdout, 10, mpq_numref (x)); printf ("/"); mpz_out_str (stdout, 10, mpq_denref (x)); printf ("\n"); }
ring_elem QQ::fraction(ring_elem top, ring_elem bottom) const { gmp_QQ result = QQ::new_elem(); mpz_set(mpq_numref(result),top.get_mpz()); mpz_set(mpq_denref(result),bottom.get_mpz()); mpq_canonicalize(result); return MPQ_RINGELEM(result); }
ring_elem Z_mod::from_rational(mpq_ptr q) const { ring_elem a = Z_mod::from_int(mpq_numref(q)); ring_elem b = Z_mod::from_int(mpq_denref(q)); if (b == _ZERO) return _ZERO; return Z_mod::divide(a,b); }
std::string Rational::toString() const { // assure the buffer is big enough to store the result assert( mpz_sizeinbase(mpq_numref(number), 10 ) + mpz_sizeinbase(mpq_denref(number), 10) + 3 < 1024 ); mpq_get_str(buffer, 10, number); return std::string(buffer); }
void clearGMPNumber(Number n) { switch(n->type) { case V_MPZ: if ( n->value.mpz->_mp_alloc ) mpz_clear(n->value.mpz); break; case V_MPQ: if ( mpq_numref(n->value.mpq)->_mp_alloc ) mpz_clear(mpq_numref(n->value.mpq)); if ( mpq_denref(n->value.mpq)->_mp_alloc ) mpz_clear(mpq_denref(n->value.mpq)); break; default: break; } }
bool set_from_mpq(elem &result, mpq_ptr a) const { ElementType n, d; set_from_mpz(n, mpq_numref(a)); set_from_mpz(d, mpq_denref(a)); if (is_zero(d)) return false; divide(result, n, d); return true; }