undo.1: Add some words about the new fake transaction id warning.
[dragonfly.git] / contrib / mpfr / div_ui.c
blob919fb9facb59ff67ce37a7bda443657277db13ed
1 /* mpfr_div_{ui,si} -- divide a floating-point number by a machine integer
3 Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao projects, INRIA.
6 This file is part of the GNU MPFR Library.
8 The GNU MPFR 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 2.1 of the License, or (at your
11 option) any later version.
13 The GNU MPFR 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 MPFR Library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #define MPFR_NEED_LONGLONG_H
24 #include "mpfr-impl.h"
26 /* returns 0 if result exact, non-zero otherwise */
27 int
28 mpfr_div_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
30 long i;
31 int sh;
32 mp_size_t xn, yn, dif;
33 mp_limb_t *xp, *yp, *tmp, c, d;
34 mp_exp_t exp;
35 int inexact, middle = 1, nexttoinf;
36 MPFR_TMP_DECL(marker);
38 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x)))
40 if (MPFR_IS_NAN (x))
42 MPFR_SET_NAN (y);
43 MPFR_RET_NAN;
45 else if (MPFR_IS_INF (x))
47 MPFR_SET_INF (y);
48 MPFR_SET_SAME_SIGN (y, x);
49 MPFR_RET (0);
51 else
53 MPFR_ASSERTD (MPFR_IS_ZERO(x));
54 if (u == 0) /* 0/0 is NaN */
56 MPFR_SET_NAN(y);
57 MPFR_RET_NAN;
59 else
61 MPFR_SET_ZERO(y);
62 MPFR_SET_SAME_SIGN (y, x);
63 MPFR_RET(0);
67 else if (MPFR_UNLIKELY (u <= 1))
69 if (u < 1)
71 /* x/0 is Inf since x != 0*/
72 MPFR_SET_INF (y);
73 MPFR_SET_SAME_SIGN (y, x);
74 MPFR_RET (0);
76 else /* y = x/1 = x */
77 return mpfr_set (y, x, rnd_mode);
79 else if (MPFR_UNLIKELY (IS_POW2 (u)))
80 return mpfr_div_2si (y, x, MPFR_INT_CEIL_LOG2 (u), rnd_mode);
82 MPFR_CLEAR_FLAGS (y);
84 MPFR_SET_SAME_SIGN (y, x);
86 MPFR_TMP_MARK (marker);
87 xn = MPFR_LIMB_SIZE (x);
88 yn = MPFR_LIMB_SIZE (y);
90 xp = MPFR_MANT (x);
91 yp = MPFR_MANT (y);
92 exp = MPFR_GET_EXP (x);
94 dif = yn + 1 - xn;
96 /* we need to store yn+1 = xn + dif limbs of the quotient */
97 /* don't use tmp=yp since the mpn_lshift call below requires yp >= tmp+1 */
98 tmp = (mp_limb_t*) MPFR_TMP_ALLOC ((yn + 1) * BYTES_PER_MP_LIMB);
100 c = (mp_limb_t) u;
101 MPFR_ASSERTN (u == c);
102 if (dif >= 0)
103 c = mpn_divrem_1 (tmp, dif, xp, xn, c); /* used all the dividend */
104 else /* dif < 0 i.e. xn > yn, don't use the (-dif) low limbs from x */
105 c = mpn_divrem_1 (tmp, 0, xp - dif, yn + 1, c);
107 inexact = (c != 0);
109 /* First pass in estimating next bit of the quotient, in case of RNDN *
110 * In case we just have the right number of bits (postpone this ?), *
111 * we need to check whether the remainder is more or less than half *
112 * the divisor. The test must be performed with a subtraction, so as *
113 * to prevent carries. */
115 if (MPFR_LIKELY (rnd_mode == GMP_RNDN))
117 if (c < (mp_limb_t) u - c) /* We have u > c */
118 middle = -1;
119 else if (c > (mp_limb_t) u - c)
120 middle = 1;
121 else
122 middle = 0; /* exactly in the middle */
125 /* If we believe that we are right in the middle or exact, we should check
126 that we did not neglect any word of x (division large / 1 -> small). */
128 for (i=0; ((inexact == 0) || (middle == 0)) && (i < -dif); i++)
129 if (xp[i])
130 inexact = middle = 1; /* larger than middle */
133 If the high limb of the result is 0 (xp[xn-1] < u), remove it.
134 Otherwise, compute the left shift to be performed to normalize.
135 In the latter case, we discard some low bits computed. They
136 contain information useful for the rounding, hence the updating
137 of middle and inexact.
140 if (tmp[yn] == 0)
142 MPN_COPY(yp, tmp, yn);
143 exp -= BITS_PER_MP_LIMB;
145 else
147 int shlz;
149 count_leading_zeros (shlz, tmp[yn]);
151 /* shift left to normalize */
152 if (MPFR_LIKELY (shlz != 0))
154 mp_limb_t w = tmp[0] << shlz;
156 mpn_lshift (yp, tmp + 1, yn, shlz);
157 yp[0] += tmp[0] >> (BITS_PER_MP_LIMB - shlz);
159 if (w > (MPFR_LIMB_ONE << (BITS_PER_MP_LIMB - 1)))
160 { middle = 1; }
161 else if (w < (MPFR_LIMB_ONE << (BITS_PER_MP_LIMB - 1)))
162 { middle = -1; }
163 else
164 { middle = (c != 0); }
166 inexact = inexact || (w != 0);
167 exp -= shlz;
169 else
170 { /* this happens only if u == 1 and xp[xn-1] >=
171 1<<(BITS_PER_MP_LIMB-1). It might be better to handle the
172 u == 1 case seperately ?
175 MPN_COPY (yp, tmp + 1, yn);
179 MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (y));
180 /* it remains sh bits in less significant limb of y */
182 d = *yp & MPFR_LIMB_MASK (sh);
183 *yp ^= d; /* set to zero lowest sh bits */
185 MPFR_TMP_FREE (marker);
187 if (exp < __gmpfr_emin - 1)
188 return mpfr_underflow (y, rnd_mode == GMP_RNDN ? GMP_RNDZ : rnd_mode,
189 MPFR_SIGN (y));
191 if (MPFR_UNLIKELY (d == 0 && inexact == 0))
192 nexttoinf = 0; /* result is exact */
193 else
194 switch (rnd_mode)
196 case GMP_RNDZ:
197 inexact = - MPFR_INT_SIGN (y); /* result is inexact */
198 nexttoinf = 0;
199 break;
201 case GMP_RNDU:
202 inexact = 1;
203 nexttoinf = MPFR_IS_POS (y);
204 break;
206 case GMP_RNDD:
207 inexact = -1;
208 nexttoinf = MPFR_IS_NEG (y);
209 break;
211 default:
212 MPFR_ASSERTD (rnd_mode == GMP_RNDN);
213 /* We have one more significant bit in yn. */
214 if (sh && d < (MPFR_LIMB_ONE << (sh - 1)))
216 inexact = - MPFR_INT_SIGN (y);
217 nexttoinf = 0;
219 else if (sh && d > (MPFR_LIMB_ONE << (sh - 1)))
221 inexact = MPFR_INT_SIGN (y);
222 nexttoinf = 1;
224 else /* sh = 0 or d = 1 << (sh-1) */
226 /* The first case is "false" even rounding (significant bits
227 indicate even rounding, but the result is inexact, so up) ;
228 The second case is the case where middle should be used to
229 decide the direction of rounding (no further bit computed) ;
230 The third is the true even rounding.
232 if ((sh && inexact) || (!sh && middle > 0) ||
233 (!inexact && *yp & (MPFR_LIMB_ONE << sh)))
235 inexact = MPFR_INT_SIGN (y);
236 nexttoinf = 1;
238 else
240 inexact = - MPFR_INT_SIGN (y);
241 nexttoinf = 0;
246 if (nexttoinf &&
247 MPFR_UNLIKELY (mpn_add_1 (yp, yp, yn, MPFR_LIMB_ONE << sh)))
249 exp++;
250 yp[yn-1] = MPFR_LIMB_HIGHBIT;
253 /* Set the exponent. Warning! One may still have an underflow. */
254 MPFR_EXP (y) = exp;
256 return mpfr_check_range (y, inexact, rnd_mode);
259 int mpfr_div_si (mpfr_ptr y, mpfr_srcptr x, long int u, mp_rnd_t rnd_mode)
261 int res;
263 if (u >= 0)
264 res = mpfr_div_ui (y, x, u, rnd_mode);
265 else
267 res = -mpfr_div_ui (y, x, -u, MPFR_INVERT_RND (rnd_mode));
268 MPFR_CHANGE_SIGN (y);
270 return res;