void fmpz_tdiv_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)) { flint_printf("Exception: division by zero in fmpz_tdiv_qr\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 */ fmpz_set_si(f, q); fmpz_set_si(s, r); } else /* h is large and g is small */ { fmpz_set_ui(f, WORD(0)); /* g is zero */ fmpz_set_si(s, c1); } } 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 */ { flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), c2); } else { flint_mpz_tdiv_qr_ui(mpz_ptr, mpz_ptr2, COEFF_TO_PTR(c1), -c2); mpz_neg(mpz_ptr, mpz_ptr); } } else /* both are large */ { mpz_tdiv_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 fmpz_powm(fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m) { if (fmpz_sgn(m) <= 0) { flint_printf("Exception (fmpz_powm). Modulus is less than 1.\n"); abort(); } else if (!COEFF_IS_MPZ(*e)) /* e is small */ { fmpz_powm_ui(f, g, *e, m); } else /* e is large */ { if (!COEFF_IS_MPZ(*m)) /* m is small */ { ulong g1 = fmpz_fdiv_ui(g, *m); mpz_t g2, m2; __mpz_struct *mpz_ptr; flint_mpz_init_set_ui(g2, g1); flint_mpz_init_set_ui(m2, *m); mpz_ptr = _fmpz_promote(f); mpz_powm(mpz_ptr, g2, COEFF_TO_PTR(*e), m2); mpz_clear(g2); mpz_clear(m2); _fmpz_demote_val(f); } else /* m is large */ { if (!COEFF_IS_MPZ(*g)) /* g is small */ { mpz_t g2; __mpz_struct *mpz_ptr; flint_mpz_init_set_si(g2, *g); mpz_ptr = _fmpz_promote(f); mpz_powm(mpz_ptr, g2, COEFF_TO_PTR(*e), COEFF_TO_PTR(*m)); mpz_clear(g2); _fmpz_demote_val(f); } else /* g is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); mpz_powm(mpz_ptr, COEFF_TO_PTR(*g), COEFF_TO_PTR(*e), COEFF_TO_PTR(*m)); _fmpz_demote_val(f); } } } }
int main(void) { int i, result; flint_rand_t state; printf("fmpz...."); fflush(stdout); for (i = 0; i < 100000; i++) { fmpz_t a, b; *a = 0L; fmpz_randtest(a, state, FLINT_BITS - 2); *b = *a; _fmpz_promote_val(a); _fmpz_demote_val(a); result = (*b == *a); if (!result) { printf("FAIL\n"); abort(); } } _fmpz_cleanup(); printf("PASS\n"); return 0; }
void fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h) { fmpz c1 = *g; ulong c2 = h; if (h == 0) { printf("Exception: division by zero in fmpz_tdiv_q_ui\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (c1 > 0) { fmpz_set_ui(f, c1 / c2); } else { ulong q = ((ulong) -c1) / c2; fmpz_set_si(f, - (long) q); } } else /* g is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); mpz_tdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); _fmpz_demote_val(f); /* division by h may result in small value */ } }
void fmpz_fdiv_q(fmpz_t f, 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 (r && (c2 ^ r) < 0L) --q; fmpz_set_si(f, q); } else /* h is large and g is small */ { if ((c1 > 0L && fmpz_sgn(h) < 0) || (c1 < 0L && fmpz_sgn(h) > 0)) /* signs are the same */ fmpz_set_si(f, -1L); /* quotient is negative, round down to minus one */ else fmpz_zero(f); } } else /* g is large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); } else { mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); mpz_neg(mpz_ptr, mpz_ptr); } } else /* both are large */ { mpz_fdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); } _fmpz_demote_val(f); /* division by h may result in small value */ } }
void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(h)) { flint_printf("Exception (fmpz_divexact). Division by zero.\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small, h must be also or division isn't exact */ { fmpz_set_si(f, c1 / c2); } else /* g is large */ { __mpz_struct * mpz_ptr = _fmpz_promote(f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); _fmpz_demote_val(f); /* division by h may result in small value */ } else { flint_mpz_divexact_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); _fmpz_demote_val(f); /* division by h may result in small value */ fmpz_neg(f, f); } } else /* both are large */ { mpz_divexact(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); _fmpz_demote_val(f); /* division by h may result in small value */ } } }
void fmpz_add(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* both inputs are small */ { fmpz_set_si(f, c1 + c2); } else /* g is small, h is large */ { __mpz_struct * mpz3 = _fmpz_promote(f); /* g is saved and h is large */ __mpz_struct * mpz2 = COEFF_TO_PTR(c2); if (c1 < 0L) mpz_sub_ui(mpz3, mpz2, -c1); else mpz_add_ui(mpz3, mpz2, c1); _fmpz_demote_val(f); /* may have cancelled */ } } else { if (!COEFF_IS_MPZ(c2)) /* g is large, h is small */ { __mpz_struct * mpz3 = _fmpz_promote(f); /* h is saved and g is large */ __mpz_struct * mpz1 = COEFF_TO_PTR(c1); if (c2 < 0L) mpz_sub_ui(mpz3, mpz1, -c2); else mpz_add_ui(mpz3, mpz1, c2); _fmpz_demote_val(f); /* may have cancelled */ } else /* g and h are large */ { __mpz_struct * mpz3 = _fmpz_promote(f); /* aliasing means f is already large */ __mpz_struct * mpz1 = COEFF_TO_PTR(c1); __mpz_struct * mpz2 = COEFF_TO_PTR(c2); mpz_add(mpz3, mpz1, mpz2); _fmpz_demote_val(f); /* may have cancelled */ } } }
void fmpz_sub_ui(fmpz_t f, const fmpz_t g, ulong x) { fmpz c = *g; if (!COEFF_IS_MPZ(c)) /* coeff is small */ { mp_limb_t sum[2]; if (c < 0L) /* g negative, x positive, so difference is negative */ { add_ssaaaa(sum[1], sum[0], 0, -c, 0, x); if (sum[1] == 0) { fmpz_set_ui(f, sum[0]); /* result fits in 1 limb */ fmpz_neg(f, f); } else /* result takes two limbs */ { __mpz_struct * mpz_ptr; mpz_t temp; temp->_mp_d = sum; temp->_mp_size = -2; /* result is negative number minus negative number, hence negative */ mpz_ptr = _fmpz_promote(f); /* g has already been read */ mpz_set(mpz_ptr, temp); } } else /* coeff is non-negative, x non-negative */ { if (x < c) fmpz_set_ui(f, c - x); /* won't be negative and is smaller than c */ else { fmpz_set_ui(f, x - c); /* positive or zero */ fmpz_neg(f, f); } } } else { __mpz_struct *mpz_ptr, *mpz_ptr2; mpz_ptr = COEFF_TO_PTR(c); mpz_ptr2 = _fmpz_promote(f); /* g is already large */ mpz_sub_ui(mpz_ptr2, mpz_ptr, x); _fmpz_demote_val(f); /* cancellation may have occurred */ } }
void number_of_partitions(fmpz_t x, ulong n) { if (n < NUMBER_OF_SMALL_PARTITIONS) { fmpz_set_ui(x, partitions_lookup[n]); } else { mpfr_t t; mpfr_init(t); number_of_partitions_mpfr(t, n); mpfr_get_z(_fmpz_promote(x), t, MPFR_RNDN); _fmpz_demote_val(x); mpfr_clear(t); } }
void fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(g)) { fmpz_abs(f, h); return; } if (fmpz_is_zero(h)) { fmpz_abs(f, g); return; } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* h is also small */ { fmpz_set_si(f, z_gcd(c1, c2)); } else /* h is large, but g is small */ { fmpz c2d = fmpz_fdiv_ui(h, FLINT_ABS(c1)); fmpz_set_si(f, z_gcd(c1, c2d)); } } else { if (!COEFF_IS_MPZ(c2)) /* h is small, but g is large */ { fmpz c1d = fmpz_fdiv_ui(g, FLINT_ABS(c2)); fmpz_set_si(f, z_gcd(c2, c1d)); } else /* g and h are both large */ { __mpz_struct *mpz_ptr = _fmpz_promote(f); /* aliasing fine as g, h already large */ mpz_gcd(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); _fmpz_demote_val(f); /* gcd may be small */ } } }
void fmpz_clrbit(fmpz_t f, ulong i) { if (!COEFF_IS_MPZ(*f)) { if (i < FLINT_BITS - 2) { *f &= ~(WORD(1) << i); } /* i >= FLINT_BITS --> nop */ } else { __mpz_struct *ptr = COEFF_TO_PTR(*f); mpz_clrbit(ptr, i); _fmpz_demote_val(f); } }
void fmpz_poly_bit_pack(fmpz_t f, const fmpz_poly_t poly, mp_bitcnt_t bit_size) { long len; __mpz_struct * mpz; long i, d; int negate; len = fmpz_poly_length(poly); if (len == 0 || bit_size == 0) { fmpz_zero(f); return; } mpz = _fmpz_promote(f); mpz_realloc2(mpz, len * bit_size); d = mpz->_mp_alloc; mpn_zero(mpz->_mp_d, d); if (fmpz_sgn(fmpz_poly_lead(poly)) < 0) negate = -1; else negate = 0; _fmpz_poly_bit_pack(mpz->_mp_d, poly->coeffs, len, bit_size, negate); for (i = d - 1; i >= 0; i--) { if (mpz->_mp_d[i] != 0) break; } d = i + 1; mpz->_mp_size = d; _fmpz_demote_val(f); if (negate) fmpz_neg(f, f); }
void arf_get_fmpz(fmpz_t z, const arf_t x, arf_rnd_t rnd) { if (arf_is_special(x)) { if (arf_is_zero(x)) { fmpz_zero(z); } else { flint_printf("arf_get_fmpz: cannot convert infinity or nan to integer\n"); abort(); } } else if (COEFF_IS_MPZ(*ARF_EXPREF(x))) { /* tiny */ if (fmpz_sgn(ARF_EXPREF(x)) < 0) { int negative = ARF_SGNBIT(x); if (rnd == ARF_RND_NEAR || rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } } else { flint_printf("arf_get_fmpz: number too large to convert to integer\n"); abort(); } } else { slong exp; int negative, inexact; mp_size_t xn, zn; mp_srcptr xp; __mpz_struct * zz; /* TBD: implement efficiently */ if (rnd == ARF_RND_NEAR) { fmpr_t t; fmpr_init(t); arf_get_fmpr(t, x); fmpr_get_fmpz(z, t, rnd); fmpr_clear(t); return; } exp = ARF_EXP(x); negative = ARF_SGNBIT(x); /* |x| < 1 */ if (exp <= 0) { if (rnd == ARF_RND_DOWN || (rnd == ARF_RND_FLOOR && !negative) || (rnd == ARF_RND_CEIL && negative)) { fmpz_zero(z); } else { fmpz_set_si(z, negative ? -1 : 1); } return; } ARF_GET_MPN_READONLY(xp, xn, x); /* |x| < 2^31 or 2^63 (must save 1 bit for rounding up!) */ if (exp < FLINT_BITS) { mp_limb_t v, v2; v = xp[xn - 1]; v2 = v >> (FLINT_BITS - exp); inexact = (xn > 1) || ((v2 << (FLINT_BITS - exp)) != v); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) v2++; if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) v2++; } if (negative) fmpz_neg_ui(z, v2); else fmpz_set_ui(z, v2); return; } /* |x| >= 1 */ zn = (exp + FLINT_BITS - 1) / FLINT_BITS; zz = _fmpz_promote(z); if (zz->_mp_alloc < zn) mpz_realloc2(zz, zn * FLINT_BITS); inexact = _arf_get_integer_mpn(zz->_mp_d, xp, xn, exp); zz->_mp_size = negative ? -zn : zn; _fmpz_demote_val(z); if (inexact && rnd != ARF_RND_DOWN) { if (negative && (rnd == ARF_RND_UP || rnd == ARF_RND_FLOOR)) fmpz_sub_ui(z, z, 1); if (!negative && (rnd == ARF_RND_UP || rnd == ARF_RND_CEIL)) fmpz_add_ui(z, z, 1); } }
void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m) { if (fmpz_sgn(m) <= 0) { printf("Exception (fmpz_powm_ui). Modulus is less than 1.\n"); abort(); } if (fmpz_is_one(m)) { fmpz_zero(f); } else if (e == 0) { fmpz_one(f); } else /* e != 0, m > 0 */ { fmpz g2 = *g; fmpz m2 = *m; if (!COEFF_IS_MPZ(m2)) /* m is small */ { if (!COEFF_IS_MPZ(g2)) /* g is small */ { mp_limb_t minv = n_preinvert_limb(m2); _fmpz_demote(f); if (g2 >= 0) { g2 = n_mod2_preinv(g2, m2, minv); *f = n_powmod2_preinv(g2, e, m2, minv); } else { g2 = n_mod2_preinv(-g2, m2, minv); *f = n_powmod2_preinv(g2, e, m2, minv); if ((e & 1UL)) *f = n_negmod(*f, m2); } } else /* g is large */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_t m3; mpz_init_set_ui(m3, m2); mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, m3); mpz_clear(m3); _fmpz_demote_val(f); } } else /* m is large */ { if (!COEFF_IS_MPZ(g2)) /* g is small */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_t g3; mpz_init_set_si(g3, g2); mpz_powm_ui(ptr, g3, e, COEFF_TO_PTR(m2)); mpz_clear(g3); _fmpz_demote_val(f); } else /* g is large */ { __mpz_struct *ptr = _fmpz_promote(f); mpz_powm_ui(ptr, COEFF_TO_PTR(g2), e, COEFF_TO_PTR(m2)); _fmpz_demote_val(f); } } } }
void _arith_cos_minpoly(fmpz * coeffs, slong d, ulong n) { slong i, j; fmpz * alpha; fmpz_t half; mpfr_t t, u; mp_bitcnt_t prec; slong exp; if (n <= MAX_32BIT) { for (i = 0; i <= d; i++) fmpz_set_si(coeffs + i, lookup_table[n - 1][i]); return; } /* Direct formula for odd primes > 3 */ if (n_is_prime(n)) { slong s = (n - 1) / 2; switch (s % 4) { case 0: fmpz_set_si(coeffs, WORD(1)); fmpz_set_si(coeffs + 1, -s); break; case 1: fmpz_set_si(coeffs, WORD(1)); fmpz_set_si(coeffs + 1, s + 1); break; case 2: fmpz_set_si(coeffs, WORD(-1)); fmpz_set_si(coeffs + 1, s); break; case 3: fmpz_set_si(coeffs, WORD(-1)); fmpz_set_si(coeffs + 1, -s - 1); break; } for (i = 2; i <= s; i++) { slong b = (s - i) % 2; fmpz_mul2_uiui(coeffs + i, coeffs + i - 2, s+i-b, s+2-b-i); fmpz_divexact2_uiui(coeffs + i, coeffs + i, i, i-1); fmpz_neg(coeffs + i, coeffs + i); } return; } prec = magnitude_bound(d) + 5 + FLINT_BIT_COUNT(d); alpha = _fmpz_vec_init(d); fmpz_init(half); mpfr_init2(t, prec); mpfr_init2(u, prec); fmpz_one(half); fmpz_mul_2exp(half, half, prec - 1); mpfr_const_pi(t, prec); mpfr_div_ui(t, t, n, MPFR_RNDN); for (i = j = 0; j < d; i++) { if (n_gcd(n, i) == 1) { mpfr_mul_ui(u, t, 2 * i, MPFR_RNDN); mpfr_cos(u, u, MPFR_RNDN); mpfr_neg(u, u, MPFR_RNDN); exp = mpfr_get_z_2exp(_fmpz_promote(alpha + j), u); _fmpz_demote_val(alpha + j); fmpz_mul_or_div_2exp(alpha + j, alpha + j, exp + prec); j++; } } balanced_product(coeffs, alpha, d, prec); /* Scale and round */ for (i = 0; i < d + 1; i++) { slong r = d; if ((n & (n - 1)) == 0) r--; fmpz_mul_2exp(coeffs + i, coeffs + i, r); fmpz_add(coeffs + i, coeffs + i, half); fmpz_fdiv_q_2exp(coeffs + i, coeffs + i, prec); } fmpz_clear(half); mpfr_clear(t); mpfr_clear(u); _fmpz_vec_clear(alpha, d); }
void fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x) { fmpz c1, r; c1 = *g; if ((x == 0) || (c1 == 0)) /* product is zero */ return; r = *f; if (r == 0) { fmpz_mul_ui(f, g, x); /* we are adding product to 0 */ return; } if (x == UWORD(1)) /* special case, adding g*1 to f */ { fmpz_add(f, f, g); return; } if (c1 == UWORD(1)) /* special case, adding 1*x to f */ { fmpz_add_ui(f, f, x); return; } if (!COEFF_IS_MPZ(c1)) /* c1 is small */ { mp_limb_t prod[2]; ulong uc1 = FLINT_ABS(c1); umul_ppmm(prod[1], prod[0], uc1, x); /* compute product */ if (prod[1] == 0) /* product fits in one limb */ { if (c1 < WORD(0)) fmpz_sub_ui(f, f, prod[0]); else fmpz_add_ui(f, f, prod[0]); return; } else if ((prod[1] == 1) && (!COEFF_IS_MPZ(r)) && ((r ^ c1) < WORD(0))) { /* only chance at cancellation is if product is one bit past a limb and res is small and opposite sign to this product */ ulong ur = FLINT_ABS(r); if (ur > prod[0]) /* cancellation will occur */ { fmpz_set_ui(f, prod[0] - ur); if (r > WORD(0)) fmpz_neg(f, f); return; } } /* in all remaining cases res is either big already, or will be big in the end */ { __mpz_struct * mpz_ptr = _fmpz_promote_val(f); mpz_t temp; /* set up a temporary, cheap mpz_t to contain prod */ temp->_mp_d = prod; temp->_mp_size = (c1 < WORD(0) ? -2 : 2); mpz_add(mpz_ptr, mpz_ptr, temp); _fmpz_demote_val(f); /* cancellation may have occurred */ } } else /* c1 is large */ { __mpz_struct * mpz_ptr = _fmpz_promote_val(f); flint_mpz_addmul_ui(mpz_ptr, COEFF_TO_PTR(c1), x); _fmpz_demote_val(f); /* cancellation may have occurred */ } }
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 */ } }