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_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 _brute_force_all_pairs_longest_walk(fmpz_mat_t B, const bool_mat_t A) { slong i, j, n; n = bool_mat_nrows(A); /* set entries of B according to the longest observed walk */ { slong k; bool_mat_t T; bool_mat_init(T, n, n); bool_mat_one(T); fmpz_mat_zero(B); for (k = 0; k < 2*n+1; k++) { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (bool_mat_get_entry(T, i, j)) { fmpz_set_si(fmpz_mat_entry(B, i, j), k); } } } bool_mat_mul(T, T, A); } bool_mat_clear(T); } /* set special values 0, -1, -2 */ { for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { slong x; fmpz *p; p = fmpz_mat_entry(B, i, j); x = fmpz_get_si(p); if (x < 1) { x = (i == j) ? 0 : -1; } else if (x > n-1) { x = -2; } fmpz_set_si(p, x); } } } }
void elem_set_si(elem_ptr elem, long v, const ring_t ring) { switch (ring->type) { case TYPE_FMPZ: fmpz_set_si(elem, v); break; case TYPE_LIMB: *((mp_ptr) elem) = v; break; case TYPE_POLY: elem_poly_set_si(elem, v, ring); break; case TYPE_MOD: { switch (RING_PARENT(ring)->type) { case TYPE_FMPZ: fmpz_set_si(elem, v); fmpz_mod(elem, elem, RING_MODULUS(ring)); break; case TYPE_LIMB: *((mp_ptr) elem) = nmod_set_si(v, ring->nmod); break; default: NOT_IMPLEMENTED("set_si (mod)", ring); } } break; case TYPE_FRAC: elem_set_si(NUMER(elem, ring), v, RING_NUMER(ring)); elem_one(DENOM(elem, ring), RING_DENOM(ring)); break; case TYPE_COMPLEX: elem_set_si(REALPART(elem, ring), v, ring->parent); elem_zero(IMAGPART(elem, ring), ring->parent); break; default: NOT_IMPLEMENTED("set_si", ring); } }
int main(int argc, char* argv[]) { fmpz_t c, n; long N = 0; if (argc == 2) N = atol(argv[1]); if (argc != 2 || N < 1) { printf("Syntax: delta_qexp <integer>\n"); printf("where <integer> is the (positive) number of terms to compute\n"); return EXIT_FAILURE; } fmpz_init(c); fmpz_init(n); fmpz_set_si(n, N); fmpz_ramanujan_tau(c, n); printf("Coefficient of q^%ld is ", N); fmpz_print(c); printf("\n"); fmpz_clear(c); fmpz_clear(n); return EXIT_SUCCESS; }
void _fmpz_holonomic_eval_companion_matrix_fmpz(fmpz_mat_t M, fmpz_t Q, const fmpz_holonomic_t op, long n) { fmpz_t c; long r = fmpz_holonomic_order(op); long i, j; fmpz_init(c); fmpz_set_si(c, n); fmpz_poly_evaluate_fmpz(Q, op->coeffs + r, c); for (i = 0; i < r - 1; i++) { for (j = 0; j < r; j++) { if (i + 1 == j) fmpz_set(M->rows[i] + j, Q); else fmpz_zero(M->rows[i] + j); } } for (j = 0; j < r; j++) { fmpz_poly_evaluate_fmpz(M->rows[r - 1] + j, op->coeffs + j, c); fmpz_neg(M->rows[r - 1] + j, M->rows[r - 1] + j); } fmpz_clear(c); }
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_multi_CRT_sign(fmpz_t output, fmpz_t input, fmpz_comb_t comb) { unsigned long n = comb->n; if (n == 0L) { if (input[0] == 0L) { fmpz_set_ui(output, 0L); return; } unsigned long p = comb->primes[0]; if ((p - input[1]) < input[1]) fmpz_set_si(output, (long) (input[1] - p)); else fmpz_set_ui(output, input[1]); return; } fmpz_t temp = fmpz_init(fmpz_size(comb->comb[n-1][0]) + 1); fmpz_sub(temp, input, comb->comb[comb->n - 1][0]); if (fmpz_cmpabs(temp, input) <= 0L) fmpz_set(output, temp); else fmpz_set(output, input); fmpz_clear(temp); return; }
/* Compute a pure ratio P2(k)/Q2(k) for the term A(k)/B(k) * [P(1)P(2)...P(k)] / [Q(1)Q(2)...Q(k)] */ void hypgeom_standardize(fmpz_poly_t P2, fmpz_poly_t Q2, const fmpz_poly_t A, const fmpz_poly_t B, const fmpz_poly_t P, const fmpz_poly_t Q) { fmpz_t s; fmpz_poly_t T; fmpz_init(s); fmpz_poly_init(T); fmpz_set_si(s, -WORD(1)); /* P = A * B(k-1) * P */ fmpz_poly_taylor_shift(T, B, s); fmpz_poly_mul(P2, A, T); fmpz_poly_mul(P2, P2, P); /* Q = B * A(k-1) * Q */ fmpz_poly_taylor_shift(T, A, s); fmpz_poly_mul(Q2, B, T); fmpz_poly_mul(Q2, Q2, Q); fmpz_clear(s); fmpz_poly_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 */ } } }
int main(void) { long i; fmpz_t x; printf("abs_fits_ui...."); fflush(stdout); fmpz_init(x); fmpz_set_si(x, COEFF_MIN); check(x, 1); fmpz_set_si(x, COEFF_MAX); check(x, 1); fmpz_set_ui(x, ULONG_MAX); check(x, 1); fmpz_set_ui(x, ULONG_MAX); fmpz_neg(x, x); check(x, 1); fmpz_set_ui(x, ULONG_MAX); fmpz_add_ui(x, x, 1UL); check(x, 0); fmpz_neg(x, x); check(x, 0); for (i = 0; i < 1000; i++) { fmpz_set_ui(x, 1UL); fmpz_mul_2exp(x, x, i); check(x, i < FLINT_BITS); fmpz_neg(x, x); check(x, i < FLINT_BITS); } fmpz_clear(x); _fmpz_cleanup(); printf("PASS\n"); return 0; }
void fmpr_pow_sloppy_si(fmpr_t y, const fmpr_t b, long e, long prec, fmpr_rnd_t rnd) { fmpz_t f; fmpz_init(f); fmpz_set_si(f, e); fmpr_pow_sloppy_fmpz(y, b, f, prec, rnd); fmpz_clear(f); }
void acb_pow_si(acb_t y, const acb_t b, long e, long prec) { fmpz_t f; fmpz_init(f); fmpz_set_si(f, e); acb_pow_fmpz(y, b, f, prec); fmpz_clear(f); }
void renf_elem_class::assign(slong value) noexcept { if (nf == nullptr) { fmpz_one(fmpq_denref(b)); fmpz_set_si(fmpq_numref(b), value); } else renf_elem_set_si(a, value, nf->renf_t()); }
static void _padic_log_bsplit_series(fmpz_t P, fmpz_t B, fmpz_t T, const fmpz_t x, long a, long b) { if (b - a == 1) { fmpz_set(P, x); fmpz_set_si(B, a); fmpz_set(T, x); } else if (b - a == 2) { fmpz_mul(P, x, x); fmpz_set_si(B, a); fmpz_mul_si(B, B, a + 1); fmpz_mul_si(T, x, a + 1); fmpz_addmul_ui(T, P, a); } else { const long m = (a + b) / 2; fmpz_t RP, RB, RT; _padic_log_bsplit_series(P, B, T, x, a, m); fmpz_init(RP); fmpz_init(RB); fmpz_init(RT); _padic_log_bsplit_series(RP, RB, RT, x, m, b); fmpz_mul(RT, RT, P); fmpz_mul(T, T, RB); fmpz_addmul(T, RT, B); fmpz_mul(P, P, RP); fmpz_mul(B, B, RB); fmpz_clear(RP); fmpz_clear(RB); fmpz_clear(RT); } }
void poly_starmultiply(fmpz_poly_t c, const fmpz_poly_t a, const fmpz_poly_t b, const ntru_params *params, uint32_t modulus) { fmpz_poly_t a_tmp; fmpz_t c_coeff_k; fmpz_poly_init(a_tmp); fmpz_init(c_coeff_k); /* avoid side effects */ fmpz_poly_set(a_tmp, a); fmpz_poly_zero(c); for (int k = params->N - 1; k >= 0; k--) { int j; j = k + 1; fmpz_set_si(c_coeff_k, 0); for (int i = params->N - 1; i >= 0; i--) { fmpz *a_tmp_coeff_i, *b_coeff_j; if (j == (int)(params->N)) j = 0; a_tmp_coeff_i = fmpz_poly_get_coeff_ptr(a_tmp, i); b_coeff_j = fmpz_poly_get_coeff_ptr(b, j); if (fmpz_cmp_si_n(a_tmp_coeff_i, 0) && fmpz_cmp_si_n(b_coeff_j, 0)) { fmpz_t fmpz_tmp; fmpz_init(fmpz_tmp); fmpz_mul(fmpz_tmp, a_tmp_coeff_i, b_coeff_j); fmpz_add(fmpz_tmp, fmpz_tmp, c_coeff_k); fmpz_mod_ui(c_coeff_k, fmpz_tmp, modulus); fmpz_poly_set_coeff_fmpz(c, k, c_coeff_k); fmpz_clear(fmpz_tmp); } j++; } fmpz_clear(c_coeff_k); } fmpz_poly_clear(a_tmp); }
void test_0( slong x ) { fmpz_t t; fmpz_init(t); fmpz_set_si( t, x ); test_1( t ); grow( t ); test_1( t ); grow( t ); test_1( t ); fmpz_clear(t); }
void fmpz_mat_det_divisor(fmpz_t d, const fmpz_mat_t A) { fmpz_mat_t X, B; fmpz_t t, u, v, mod; long i, n; int success; n = A->r; fmpz_mat_init(B, n, 1); fmpz_mat_init(X, n, 1); fmpz_init(t); fmpz_init(u); fmpz_init(v); fmpz_init(mod); /* Create a "random" vector */ for (i = 0; i < n; i++) { fmpz_set_si(fmpz_mat_entry(B, i, 0), 2*(i % 2) - 1); } success = fmpz_mat_solve_dixon(X, mod, A, B); if (success) { fmpz_one(d); for (i = 0; i < n; i++) { fmpz_mul(t, d, fmpz_mat_entry(X, i, 0)); fmpz_fdiv_qr(u, t, t, mod); if (!_fmpq_reconstruct_fmpz(u, v, t, mod)) { printf("Exception: fmpz_mat_det_divisor: " "rational reconstruction failed!\n"); abort(); } fmpz_mul(d, v, d); } } else { fmpz_zero(d); } fmpz_mat_clear(B); fmpz_mat_clear(X); fmpz_clear(t); fmpz_clear(u); fmpz_clear(v); fmpz_clear(mod); }
int main(void) { int i; FLINT_TEST_INIT(state); flint_printf("set_si...."); fflush(stdout); for (i = 0; i < 10000; i++) { fmpq_t x, y; fmpz_t p, q; slong P, Q; fmpq_init(x); fmpq_init(y); fmpz_init(p); fmpz_init(q); P = z_randtest(state); Q = n_randtest_not_zero(state); fmpz_set_si(p, P); fmpz_set_ui(q, Q); fmpq_set_fmpz_frac(x, p, q); fmpq_set_si(y, P, Q); if (!fmpq_is_canonical(y) || !fmpq_equal(x, y)) { flint_printf("FAIL"); flint_printf("p: "); fmpz_print(p); flint_printf("\n"); flint_printf("q: "); fmpz_print(q); flint_printf("\n"); flint_printf("x: "); fmpq_print(x); flint_printf("\n"); flint_printf("y: "); fmpq_print(y); flint_printf("\n"); abort(); } fmpq_clear(x); fmpq_clear(y); fmpz_clear(p); fmpz_clear(q); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
int fmpz_cmp_si_n(const fmpz_t f, slong g) { fmpz_t f_cmp; fmpz_init(f_cmp); if (f) fmpz_set(f_cmp, f); else fmpz_set_si(f_cmp, 0); return fmpz_cmp_si(f_cmp, g); }
void mag_expinv(mag_t res, const mag_t x) { if (mag_is_zero(x)) { mag_one(res); } else if (mag_is_inf(x)) { mag_zero(res); } else if (fmpz_sgn(MAG_EXPREF(x)) <= 0) { mag_one(res); } else if (fmpz_cmp_ui(MAG_EXPREF(x), 2 * MAG_BITS) > 0) { fmpz_t t; fmpz_init(t); /* If x > 2^60, exp(-x) < 2^(-2^60 / log(2)) */ /* -1/log(2) < -369/256 */ fmpz_set_si(t, -369); fmpz_mul_2exp(t, t, 2 * MAG_BITS - 8); mag_one(res); mag_mul_2exp_fmpz(res, res, t); fmpz_clear(t); } else { fmpz_t t; slong e = MAG_EXP(x); fmpz_init(t); fmpz_set_ui(t, MAG_MAN(x)); if (e >= MAG_BITS) fmpz_mul_2exp(t, t, e - MAG_BITS); else fmpz_tdiv_q_2exp(t, t, MAG_BITS - e); /* upper bound for 1/e */ mag_set_ui_2exp_si(res, 395007543, -30); mag_pow_fmpz(res, res, t); fmpz_clear(t); } }
void fmpz_poly_set_coeff_si(fmpz_poly_t poly, long n, long x) { fmpz_poly_fit_length(poly, n + 1); if (n + 1 > poly->length) /* insert zeroes between end of poly and new coeff if needed */ { mpn_zero((mp_ptr) (poly->coeffs + poly->length), n - poly->length); poly->length = n + 1; } fmpz_set_si(poly->coeffs + n, x); _fmpz_poly_normalise(poly); /* we may have set leading coefficient to zero */ }
void fmpz_poly_q_scalar_mul_si(fmpz_poly_q_t rop, const fmpz_poly_q_t op, long x) { fmpz_t cont, fx, gcd; if (fmpz_poly_q_is_zero(op) || (x == 0)) { fmpz_poly_q_zero(rop); return; } if (x == 1) { fmpz_poly_q_set(rop, op); return; } fmpz_init(cont); fmpz_poly_content(cont, op->den); if (fmpz_is_one(cont)) { fmpz_poly_scalar_mul_si(rop->num, op->num, x); fmpz_poly_set(rop->den, op->den); fmpz_clear(cont); return; } fmpz_init(fx); fmpz_init(gcd); fmpz_set_si(fx, x); fmpz_gcd(gcd, cont, fx); if (fmpz_is_one(gcd)) { fmpz_poly_scalar_mul_si(rop->num, op->num, x); fmpz_poly_set(rop->den, op->den); } else { fmpz_divexact(fx, fx, gcd); fmpz_poly_scalar_mul_fmpz(rop->num, op->num, fx); fmpz_poly_scalar_divexact_fmpz(rop->den, op->den, gcd); } fmpz_clear(cont); fmpz_clear(fx); fmpz_clear(gcd); }
int main(void) { long i; fmpz_t x; printf("fits_si...."); fflush(stdout); fmpz_init(x); fmpz_set_si(x, COEFF_MIN); check(x, 1); fmpz_set_si(x, COEFF_MAX); check(x, 1); fmpz_set_si(x, LONG_MAX); check(x, 1); fmpz_set_si(x, LONG_MIN); check(x, 1); fmpz_set_ui(x, ULONG_MAX); check(x, 0); fmpz_set_ui(x, ULONG_MAX); fmpz_neg(x, x); check(x, 0); fmpz_set_si(x, LONG_MAX); fmpz_add_ui(x, x, 1); check(x, 0); fmpz_set_si(x, LONG_MIN); fmpz_sub_ui(x, x, 1); check(x, 0); for (i = 0; i < 1000; i++) { fmpz_set_ui(x, 1); fmpz_mul_2exp(x, x, i); check(x, i < FLINT_BITS - 1); fmpz_neg(x, x); check(x, i < FLINT_BITS); /* LONG_MIN fits */ } fmpz_clear(x); _fmpz_cleanup(); printf("PASS\n"); return EXIT_SUCCESS; }
void _fmpq_poly_scalar_div_si(fmpz * rpoly, fmpz_t rden, const fmpz * poly, const fmpz_t den, long len, long c) { if (c == 1) { if (rpoly != poly) { _fmpz_vec_set(rpoly, poly, len); fmpz_set(rden, den); } } else if (c == -1) { _fmpz_vec_neg(rpoly, poly, len); fmpz_set(rden, den); } else { fmpz_t d, f; fmpz_init(d); fmpz_init(f); fmpz_set_si(f, c); _fmpz_vec_content(d, poly, len); fmpz_gcd(d, d, f); if (c > 0) { _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_si(rden, den, c / fmpz_get_si(d)); } else { ulong q = (- (ulong) c) / fmpz_get_ui(d); fmpz_neg(d, d); _fmpz_vec_scalar_divexact_fmpz(rpoly, poly, len, d); fmpz_mul_ui(rden, den, q); } fmpz_clear(d); fmpz_clear(f); } }
void fmpz_set_mpf(fmpz_t f, const mpf_t x) { #if defined(__MPIR_VERSION) if (mpf_fits_si_p(x)) #else if (flint_mpf_fits_slong_p(x)) #endif { slong cx = flint_mpf_get_si(x); fmpz_set_si(f, cx); } else { __mpz_struct *z = _fmpz_promote(f); mpz_set_f(z, x); } }
/* requires x != 1 */ static void arf_log_via_mpfr(arf_t z, const arf_t x, slong prec, arf_rnd_t rnd) { mpfr_t xf, zf; mp_ptr zptr, tmp; mp_srcptr xptr; mp_size_t xn, zn, val; TMP_INIT; TMP_START; zn = (prec + FLINT_BITS - 1) / FLINT_BITS; tmp = TMP_ALLOC(zn * sizeof(mp_limb_t)); ARF_GET_MPN_READONLY(xptr, xn, x); xf->_mpfr_d = (mp_ptr) xptr; xf->_mpfr_prec = xn * FLINT_BITS; xf->_mpfr_sign = ARF_SGNBIT(x) ? -1 : 1; xf->_mpfr_exp = ARF_EXP(x); zf->_mpfr_d = tmp; zf->_mpfr_prec = prec; zf->_mpfr_sign = 1; zf->_mpfr_exp = 0; mpfr_set_emin(MPFR_EMIN_MIN); mpfr_set_emax(MPFR_EMAX_MAX); mpfr_log(zf, xf, arf_rnd_to_mpfr(rnd)); val = 0; while (tmp[val] == 0) val++; ARF_GET_MPN_WRITE(zptr, zn - val, z); flint_mpn_copyi(zptr, tmp + val, zn - val); if (zf->_mpfr_sign < 0) ARF_NEG(z); fmpz_set_si(ARF_EXPREF(z), zf->_mpfr_exp); TMP_END; }
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_poly_bit_unpack(fmpz_poly_t poly, const fmpz_t f, mp_bitcnt_t bit_size) { slong len; mpz_t tmp; int negate, borrow; if (bit_size == 0 || fmpz_is_zero(f)) { fmpz_poly_zero(poly); return; } /* Round up */ len = (fmpz_bits(f) + bit_size - 1) / bit_size; negate = (fmpz_sgn(f) < 0) ? -1 : 0; mpz_init2(tmp, bit_size*len); /* TODO: avoid all this wastefulness */ flint_mpn_zero(tmp->_mp_d, tmp->_mp_alloc); fmpz_get_mpz(tmp, f); fmpz_poly_fit_length(poly, len + 1); borrow = _fmpz_poly_bit_unpack(poly->coeffs, len, tmp->_mp_d, bit_size, negate); if (borrow) { fmpz_set_si(poly->coeffs + len, negate ? WORD(-1) : WORD(1)); _fmpz_poly_set_length(poly, len + 1); } else { _fmpz_poly_set_length(poly, len); _fmpz_poly_normalise(poly); } mpz_clear(tmp); }
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 */ } } }