static void check_one (mp_ptr qp, mp_srcptr rp, mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn, const char *fname, mp_limb_t q_allowed_err) { mp_size_t qn = nn - dn + 1; mp_ptr tp; const char *msg; const char *tvalue; mp_limb_t i; TMP_DECL; TMP_MARK; tp = TMP_ALLOC_LIMBS (nn + 1); if (dn >= qn) refmpn_mul (tp, dp, dn, qp, qn); else refmpn_mul (tp, qp, qn, dp, dn); for (i = 0; i < q_allowed_err && (tp[nn] > 0 || mpn_cmp (tp, np, nn) > 0); i++) ASSERT_NOCARRY (refmpn_sub (tp, tp, nn+1, dp, dn)); if (tp[nn] > 0 || mpn_cmp (tp, np, nn) > 0) { msg = "q too large"; tvalue = "Q*D"; error: printf ("\r*******************************************************************************\n"); printf ("%s failed test %ld: %s\n", fname, test, msg); printf ("N= "); dumpy (np, nn); printf ("D= "); dumpy (dp, dn); printf ("Q= "); dumpy (qp, qn); if (rp) { printf ("R= "); dumpy (rp, dn); } printf ("%5s=", tvalue); dumpy (tp, nn+1); printf ("nn = %ld, dn = %ld, qn = %ld\n", nn, dn, qn); abort (); } ASSERT_NOCARRY (refmpn_sub_n (tp, np, tp, nn)); tvalue = "N-Q*D"; if (!mpn_zero_p (tp + dn, nn - dn) || mpn_cmp (tp, dp, dn) >= 0) { msg = "q too small"; goto error; } if (rp && mpn_cmp (rp, tp, dn) != 0) { msg = "r incorrect"; goto error; } TMP_FREE; }
static void refmpz_mul (mpz_t w, const mpz_t u, const mpz_t v) { mp_size_t usize = u->_mp_size; mp_size_t vsize = v->_mp_size; mp_size_t wsize; mp_size_t sign_product; mp_ptr up, vp; mp_ptr wp; mp_size_t talloc; sign_product = usize ^ vsize; usize = ABS (usize); vsize = ABS (vsize); if (usize == 0 || vsize == 0) { SIZ (w) = 0; return; } talloc = usize + vsize; up = u->_mp_d; vp = v->_mp_d; wp = __GMP_ALLOCATE_FUNC_LIMBS (talloc); if (usize > vsize) refmpn_mul (wp, up, usize, vp, vsize); else refmpn_mul (wp, vp, vsize, up, usize); wsize = usize + vsize; wsize -= wp[wsize - 1] == 0; MPZ_REALLOC (w, wsize); MPN_COPY (PTR(w), wp, wsize); SIZ(w) = sign_product < 0 ? -wsize : wsize; __GMP_FREE_FUNC_LIMBS (wp, talloc); }
static int invert_valid (mp_srcptr ip, mp_srcptr dp, mp_size_t n) { mp_ptr tp; int cy; TMP_DECL; TMP_MARK; tp = TMP_ALLOC_LIMBS (2*n); refmpn_mul (tp, ip, n, dp, n); cy = refmpn_add_n (tp + n, tp + n, dp, n); /* This must not give a carry. */ cy -= refmpn_add (tp, tp, 2*n, dp, n); /* This must give a carry. */ TMP_FREE; return (cy == -1); }