mpz_divexact
Torbjorn Granlund
tg at gmplib.org
Fri Dec 18 15:15:35 CET 2009
nisse at lysator.liu.se (Niels Möller) writes:
I've rewritten mpz_divexact in terms of mpn_divexact, result attached.
Cool!
Should I check this in straight away?
Sure. Some suggestions:
Please shorten variable life ranges of np, dp, qp by doing them later.
Use MPZ_REALLOC.
Use the PTR ans SIZ macros.
Remove the defunct references to Kenneth's work, mention in the
"Contributed by" that you wrote this code.
(I'll remove mpn_bdivmod after you've checked this in, I have a patch
ready.)
With these and some other minor changes, the code becomes the following:
/* mpz_divexact -- finds quotient when known that quot * den == num && den != 0.
Contributed to the GNU project by Niels Möller.
Copyright 1991, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2005,
2006, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
#include "gmp.h"
#include "gmp-impl.h"
#include "longlong.h"
void
mpz_divexact (mpz_ptr quot, mpz_srcptr num, mpz_srcptr den)
{
mp_ptr qp;
mp_size_t qn;
mp_srcptr np, dp;
mp_size_t nn, dn;
TMP_DECL;
#if WANT_ASSERT
{
mpz_t rem;
mpz_init (rem);
mpz_tdiv_r (rem, num, den);
ASSERT (SIZ(rem) == 0);
mpz_clear (rem);
}
#endif
nn = ABSIZ (num);
dn = ABSIZ (den);
qn = nn - dn + 1;
MPZ_REALLOC (quot, qn);
if (nn < dn)
{
/* This special case avoids segfaults below when the function is
incorrectly called with |N| < |D|, N != 0. It also handles the
well-defined case N = 0. */
SIZ(quot) = 0;
return;
}
TMP_MARK;
qp = PTR(quot);
if (quot == num || quot == den)
qp = TMP_ALLOC_LIMBS (qn);
np = PTR(num);
dp = PTR(den);
mpn_divexact (qp, np, nn, dp, dn);
MPN_NORMALIZE (qp, qn);
SIZ(quot) = (nn ^ dn) >= 0 ? qn : -qn;
if (qp != PTR(quot))
MPN_COPY (PTR(quot), qp, qn);
TMP_FREE;
}
--
Torbjörn
More information about the gmp-devel
mailing list