1/* mpz_divexact_ui -- exact division mpz by ulong.
2
3Copyright 2001, 2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The GNU MP Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19
20#include "gmp.h"
21#include "gmp-impl.h"
22
23void
24mpz_divexact_ui (mpz_ptr dst, mpz_srcptr src, unsigned long divisor)
25{
26  mp_size_t  size, abs_size;
27  mp_ptr     dst_ptr;
28
29  if (divisor == 0)
30    DIVIDE_BY_ZERO;
31
32  /* For nails don't try to be clever if d is bigger than a limb, just fake
33     up an mpz_t and go to the main mpz_divexact.  */
34  if (divisor > GMP_NUMB_MAX)
35    {
36      mp_limb_t  dlimbs[2];
37      mpz_t      dz;
38      ALLOC(dz) = 2;
39      PTR(dz) = dlimbs;
40      mpz_set_ui (dz, divisor);
41      mpz_divexact (dst, src, dz);
42      return;
43    }
44
45  size = SIZ(src);
46  if (size == 0)
47    {
48      SIZ(dst) = 0;
49      return;
50    }
51  abs_size = ABS (size);
52
53  MPZ_REALLOC (dst, abs_size);
54  dst_ptr = PTR(dst);
55
56  MPN_DIVREM_OR_DIVEXACT_1 (dst_ptr, PTR(src), abs_size, (mp_limb_t) divisor);
57  abs_size -= (dst_ptr[abs_size-1] == 0);
58  SIZ(dst) = (size >= 0 ? abs_size : -abs_size);
59}
60