1 /* mpf_ui_div -- Divide an unsigned integer with a float.
3 Copyright 1993, 1994, 1995, 1996, 2000, 2001, 2002, 2004, 2005 Free Software
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
21 #include <stdio.h> /* for NULL */
28 mpf_ui_div (mpf_ptr r, unsigned long int u, mpf_srcptr v)
31 mp_ptr rp, tp, remp, new_vp;
33 mp_size_t rsize, prospective_rsize, zeros, tsize, high_zero;
34 mp_size_t sign_quotient;
40 sign_quotient = vsize;
44 if (UNLIKELY (vsize == 0))
47 if (UNLIKELY (u == 0))
55 rexp = 1 - v->_mp_exp + 1;
60 prospective_rsize = 1 - vsize + 1; /* quot from using given u,v sizes */
61 rsize = prec + 1; /* desired quot size */
63 zeros = rsize - prospective_rsize; /* padding u to give rsize */
64 tsize = 1 + zeros; /* u with zeros */
68 /* separate alloc blocks, for malloc debugging */
69 remp = TMP_ALLOC_LIMBS (vsize);
70 tp = TMP_ALLOC_LIMBS (tsize);
73 new_vp = TMP_ALLOC_LIMBS (vsize);
77 /* one alloc with calculated size, for efficiency */
78 mp_size_t size = vsize + tsize + (rp == vp ? vsize : 0);
79 remp = TMP_ALLOC_LIMBS (size);
84 /* ensure divisor doesn't overlap quotient */
87 MPN_COPY (new_vp, vp, vsize);
91 MPN_ZERO (tp, tsize-1);
93 tp[tsize - 1] = u & GMP_NUMB_MASK;
94 #if BITS_PER_ULONG > GMP_NUMB_BITS
97 /* tsize-vsize+1 == rsize, so tsize >= rsize. rsize == prec+1 >= 2,
98 so tsize >= 2, hence there's room for 2-limb u with nails */
100 tp[tsize - 1] = u >> GMP_NUMB_BITS;
101 tp[tsize - 2] = u & GMP_NUMB_MASK;
106 ASSERT (tsize-vsize+1 == rsize);
107 mpn_tdiv_qr (rp, remp, (mp_size_t) 0, tp, tsize, vp, vsize);
109 /* strip possible zero high limb */
110 high_zero = (rp[rsize-1] == 0);
114 r->_mp_size = sign_quotient >= 0 ? rsize : -rsize;