n_pair_t fchain2_preinv(mp_limb_t m, mp_limb_t n, mp_limb_t ninv) { n_pair_t current = {0, 0}, old; int length; mp_limb_t power, xy; old.x = 2UL; old.y = n - 3UL; length = FLINT_BIT_COUNT(m); power = (1UL << (length - 1)); for (; length > 0; length--) { xy = n_mulmod2_preinv(old.x, old.y, n, ninv); xy = n_addmod(xy, 3UL, n); if (m & power) { current.y = n_submod(n_mulmod2_preinv(old.y, old.y, n, ninv), 2UL, n); current.x = xy; } else { current.x = n_submod(n_mulmod2_preinv(old.x, old.x, n, ninv), 2UL, n); current.y = xy; } power >>= 1; old = current; } return current; }
void elem_sub(elem_ptr res, elem_srcptr op1, elem_srcptr op2, const ring_t ring) { switch (ring->type) { case TYPE_FMPZ: fmpz_sub(res, op1, op2); break; case TYPE_LIMB: *((mp_ptr) res) = *((mp_srcptr) op1) - *((mp_srcptr) op2); break; case TYPE_POLY: elem_poly_sub(res, op1, op2, ring); break; case TYPE_MOD: { switch (RING_PARENT(ring)->type) { case TYPE_LIMB: *((mp_ptr) res) = n_submod(*((mp_srcptr) op1), *((mp_srcptr) op2), ring->nmod.n); break; case TYPE_FMPZ: fmpz_sub(res, op1, op2); if (fmpz_sgn(res) < 0) fmpz_add(res, res, RING_MODULUS(ring)); break; default: NOT_IMPLEMENTED("sub (mod)", ring); } } break; case TYPE_FRAC: elem_frac_sub(res, op1, op2, ring); break; case TYPE_COMPLEX: elem_sub(REALPART(res, ring), REALPART(op1, ring), REALPART(op2, ring), ring->parent); elem_sub(IMAGPART(res, ring), IMAGPART(op1, ring), IMAGPART(op2, ring), ring->parent); break; default: NOT_IMPLEMENTED("sub", ring); } }
int main(void) { int i, result; flint_rand_t state; printf("submod...."); fflush(stdout); flint_randinit(state); for (i = 0; i < 1000000; i++) { mp_limb_t a, b, d, r1, r2, s1; d = n_randtest(state); a = n_randint(state, d); b = n_randint(state, d); r1 = n_submod(a, b, d); add_ssaaaa(s1, r2, 0UL, a, 0UL, d); sub_ddmmss(s1, r2, s1, r2, 0UL, b); if ((s1) || (r2 >= d)) r2 -= d; result = (r1 == r2); if (!result) { printf("FAIL:\n"); printf("a = %lu, b = %lu, d = %lu\n", a, b, d); printf("r1 = %lu, r2 = %lu\n", r1, r2); abort(); } } flint_randclear(state); printf("PASS\n"); return 0; }
void _nmod_poly_divrem_q1(mp_ptr Q, mp_ptr R, mp_srcptr A, long lenA, mp_srcptr B, long lenB, nmod_t mod) { const mp_limb_t invL = (B[lenB-1] == 1) ? 1 : n_invmod(B[lenB-1], mod.n); if (lenB == 1) { _nmod_vec_scalar_mul_nmod(Q, A, lenA, invL, mod); } else { mp_limb_t t; Q[1] = n_mulmod2_preinv(A[lenA-1], invL, mod.n, mod.ninv); t = n_mulmod2_preinv(Q[1], B[lenB-2], mod.n, mod.ninv); t = n_submod(A[lenA-2], t, mod.n); Q[0] = n_mulmod2_preinv(t, invL, mod.n, mod.ninv); if (FLINT_BITS + 2 <= 2 * mod.norm) { mpn_mul_1(R, B, lenB - 1, Q[0]); if (lenB > 2) mpn_addmul_1(R + 1, B, lenB - 2, Q[1]); _nmod_vec_reduce(R, R, lenB - 1, mod); } else { _nmod_vec_scalar_mul_nmod(R, B, lenB - 1, Q[0], mod); if (lenB > 2) _nmod_vec_scalar_addmul_nmod(R + 1, B, lenB - 2, Q[1], mod); } _nmod_vec_sub(R, A, R, lenB - 1, mod); } }