Import mpfr-2.4.1
[dragonfly.git] / contrib / mpfr / add1.c
blobf5f30308f98972dfa3f5a8bef5c43d6511218e61
1 /* mpfr_add1 -- internal function to perform a "real" addition
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 #include "mpfr-impl.h"
25 /* compute sign(b) * (|b| + |c|) */
26 int
27 mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
29 mp_limb_t *ap, *bp, *cp;
30 mp_prec_t aq, bq, cq, aq2;
31 mp_size_t an, bn, cn;
32 mp_exp_t difw, exp;
33 int sh, rb, fb, inex;
34 mp_exp_unsigned_t diff_exp;
35 MPFR_TMP_DECL(marker);
37 MPFR_ASSERTD(MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c));
39 MPFR_TMP_MARK(marker);
41 aq = MPFR_PREC(a);
42 bq = MPFR_PREC(b);
43 cq = MPFR_PREC(c);
45 an = (aq-1)/BITS_PER_MP_LIMB+1; /* number of limbs of a */
46 aq2 = (mp_prec_t) an * BITS_PER_MP_LIMB;
47 sh = aq2 - aq; /* non-significant bits in low limb */
49 bn = (bq-1)/BITS_PER_MP_LIMB+1; /* number of limbs of b */
50 cn = (cq-1)/BITS_PER_MP_LIMB+1; /* number of limbs of c */
52 ap = MPFR_MANT(a);
53 bp = MPFR_MANT(b);
54 cp = MPFR_MANT(c);
56 if (MPFR_UNLIKELY(ap == bp))
58 bp = (mp_ptr) MPFR_TMP_ALLOC (bn * BYTES_PER_MP_LIMB);
59 MPN_COPY (bp, ap, bn);
60 if (ap == cp)
61 { cp = bp; }
63 else if (MPFR_UNLIKELY(ap == cp))
65 cp = (mp_ptr) MPFR_TMP_ALLOC (cn * BYTES_PER_MP_LIMB);
66 MPN_COPY(cp, ap, cn);
69 exp = MPFR_GET_EXP (b);
70 MPFR_SET_SAME_SIGN(a, b);
71 diff_exp = (mp_exp_unsigned_t) exp - MPFR_GET_EXP(c);
74 * 1. Compute the significant part A', the non-significant bits of A
75 * are taken into account.
77 * 2. Perform the rounding. At each iteration, we remember:
78 * _ r = rounding bit
79 * _ f = following bits (same value)
80 * where the result has the form: [number A]rfff...fff + a remaining
81 * value in the interval [0,2) ulp. We consider the most significant
82 * bits of the remaining value to update the result; a possible carry
83 * is immediately taken into account and A is updated accordingly. As
84 * soon as the bits f don't have the same value, A can be rounded.
85 * Variables:
86 * _ rb = rounding bit (0 or 1).
87 * _ fb = following bits (0 or 1), then sticky bit.
88 * If fb == 0, the only thing that can change is the sticky bit.
91 rb = fb = -1; /* means: not initialized */
93 if (MPFR_UNLIKELY(aq2 <= diff_exp))
94 { /* c does not overlap with a' */
95 if (MPFR_UNLIKELY(an > bn))
96 { /* a has more limbs than b */
97 /* copy b to the most significant limbs of a */
98 MPN_COPY(ap + (an - bn), bp, bn);
99 /* zero the least significant limbs of a */
100 MPN_ZERO(ap, an - bn);
102 else /* an <= bn */
104 /* copy the most significant limbs of b to a */
105 MPN_COPY(ap, bp + (bn - an), an);
108 else /* aq2 > diff_exp */
109 { /* c overlaps with a' */
110 mp_limb_t *a2p;
111 mp_limb_t cc;
112 mp_prec_t dif;
113 mp_size_t difn, k;
114 int shift;
116 /* copy c (shifted) into a */
118 dif = aq2 - diff_exp;
119 /* dif is the number of bits of c which overlap with a' */
121 difn = (dif-1)/BITS_PER_MP_LIMB + 1;
122 /* only the highest difn limbs from c have to be considered */
123 if (MPFR_UNLIKELY(difn > cn))
125 /* c doesn't have enough limbs; take into account the virtual
126 zero limbs now by zeroing the least significant limbs of a' */
127 MPFR_ASSERTD(difn - cn <= an);
128 MPN_ZERO(ap, difn - cn);
129 difn = cn;
131 k = diff_exp / BITS_PER_MP_LIMB;
133 /* zero the most significant k limbs of a */
134 a2p = ap + (an - k);
135 MPN_ZERO(a2p, k);
137 shift = diff_exp % BITS_PER_MP_LIMB;
139 if (MPFR_LIKELY(shift))
141 MPFR_ASSERTD(a2p - difn >= ap);
142 cc = mpn_rshift(a2p - difn, cp + (cn - difn), difn, shift);
143 if (MPFR_UNLIKELY(a2p - difn > ap))
144 *(a2p - difn - 1) = cc;
146 else
147 MPN_COPY(a2p - difn, cp + (cn - difn), difn);
149 /* add b to a */
150 cc = MPFR_UNLIKELY(an > bn)
151 ? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn)
152 : mpn_add_n(ap, ap, bp + (bn - an), an);
154 if (MPFR_UNLIKELY(cc)) /* carry */
156 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
158 inex = mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
159 goto end_of_add;
161 exp++;
162 rb = (ap[0] >> sh) & 1; /* LSB(a) --> rounding bit after the shift */
163 if (MPFR_LIKELY(sh))
165 mp_limb_t mask, bb;
167 mask = MPFR_LIMB_MASK (sh);
168 bb = ap[0] & mask;
169 ap[0] &= (~mask) << 1;
170 if (bb == 0)
171 fb = 0;
172 else if (bb == mask)
173 fb = 1;
175 mpn_rshift(ap, ap, an, 1);
176 ap[an-1] += MPFR_LIMB_HIGHBIT;
177 if (sh && fb < 0)
178 goto rounding;
179 } /* cc */
180 } /* aq2 > diff_exp */
182 /* non-significant bits of a */
183 if (MPFR_LIKELY(rb < 0 && sh))
185 mp_limb_t mask, bb;
187 mask = MPFR_LIMB_MASK (sh);
188 bb = ap[0] & mask;
189 ap[0] &= ~mask;
190 rb = bb >> (sh - 1);
191 if (MPFR_LIKELY(sh > 1))
193 mask >>= 1;
194 bb &= mask;
195 if (bb == 0)
196 fb = 0;
197 else if (bb == mask)
198 fb = 1;
199 else
200 goto rounding;
204 /* determine rounding and sticky bits (and possible carry) */
206 difw = (mp_exp_t) an - (mp_exp_t) (diff_exp / BITS_PER_MP_LIMB);
207 /* difw is the number of limbs from b (regarded as having an infinite
208 precision) that have already been combined with c; -n if the next
209 n limbs from b won't be combined with c. */
211 if (MPFR_UNLIKELY(bn > an))
212 { /* there are still limbs from b that haven't been taken into account */
213 mp_size_t bk;
215 if (fb == 0 && difw <= 0)
217 fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */
218 goto rounding;
221 bk = bn - an; /* index of lowest considered limb from b, > 0 */
222 while (difw < 0)
223 { /* ulp(next limb from b) > msb(c) */
224 mp_limb_t bb;
226 bb = bp[--bk];
228 MPFR_ASSERTD(fb != 0);
229 if (fb > 0)
231 if (bb != MP_LIMB_T_MAX)
233 fb = 1; /* c hasn't been taken into account
234 ==> sticky bit != 0 */
235 goto rounding;
238 else /* fb not initialized yet */
240 if (rb < 0) /* rb not initialized yet */
242 rb = bb >> (BITS_PER_MP_LIMB - 1);
243 bb |= MPFR_LIMB_HIGHBIT;
245 fb = 1;
246 if (bb != MP_LIMB_T_MAX)
247 goto rounding;
250 if (bk == 0)
251 { /* b has entirely been read */
252 fb = 1; /* c hasn't been taken into account
253 ==> sticky bit != 0 */
254 goto rounding;
257 difw++;
258 } /* while */
259 MPFR_ASSERTD(bk > 0 && difw >= 0);
261 if (difw <= cn)
263 mp_size_t ck;
264 mp_limb_t cprev;
265 int difs;
267 ck = cn - difw;
268 difs = diff_exp % BITS_PER_MP_LIMB;
270 if (difs == 0 && ck == 0)
271 goto c_read;
273 cprev = ck == cn ? 0 : cp[ck];
275 if (fb < 0)
277 mp_limb_t bb, cc;
279 if (difs)
281 cc = cprev << (BITS_PER_MP_LIMB - difs);
282 if (--ck >= 0)
284 cprev = cp[ck];
285 cc += cprev >> difs;
288 else
289 cc = cp[--ck];
291 bb = bp[--bk] + cc;
293 if (bb < cc /* carry */
294 && (rb < 0 || (rb ^= 1) == 0)
295 && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
297 if (exp == __gmpfr_emax)
299 inex = mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
300 goto end_of_add;
302 exp++;
303 ap[an-1] = MPFR_LIMB_HIGHBIT;
304 rb = 0;
307 if (rb < 0) /* rb not initialized yet */
309 rb = bb >> (BITS_PER_MP_LIMB - 1);
310 bb <<= 1;
311 bb |= bb >> (BITS_PER_MP_LIMB - 1);
314 fb = bb != 0;
315 if (fb && bb != MP_LIMB_T_MAX)
316 goto rounding;
317 } /* fb < 0 */
319 while (bk > 0)
321 mp_limb_t bb, cc;
323 if (difs)
325 if (ck < 0)
326 goto c_read;
327 cc = cprev << (BITS_PER_MP_LIMB - difs);
328 if (--ck >= 0)
330 cprev = cp[ck];
331 cc += cprev >> difs;
334 else
336 if (ck == 0)
337 goto c_read;
338 cc = cp[--ck];
341 bb = bp[--bk] + cc;
342 if (bb < cc) /* carry */
344 fb ^= 1;
345 if (fb)
346 goto rounding;
347 rb ^= 1;
348 if (rb == 0 && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
350 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
352 inex = mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
353 goto end_of_add;
355 exp++;
356 ap[an-1] = MPFR_LIMB_HIGHBIT;
358 } /* bb < cc */
360 if (!fb && bb != 0)
362 fb = 1;
363 goto rounding;
365 if (fb && bb != MP_LIMB_T_MAX)
366 goto rounding;
367 } /* while */
369 /* b has entirely been read */
371 if (fb || ck < 0)
372 goto rounding;
373 if (difs && cprev << (BITS_PER_MP_LIMB - difs))
375 fb = 1;
376 goto rounding;
378 while (ck)
380 if (cp[--ck])
382 fb = 1;
383 goto rounding;
385 } /* while */
386 } /* difw <= cn */
387 else
388 { /* c has entirely been read */
389 c_read:
390 if (fb < 0) /* fb not initialized yet */
392 mp_limb_t bb;
394 MPFR_ASSERTD(bk > 0);
395 bb = bp[--bk];
396 if (rb < 0) /* rb not initialized yet */
398 rb = bb >> (BITS_PER_MP_LIMB - 1);
399 bb &= ~MPFR_LIMB_HIGHBIT;
401 fb = bb != 0;
402 } /* fb < 0 */
403 if (fb)
404 goto rounding;
405 while (bk)
407 if (bp[--bk])
409 fb = 1;
410 goto rounding;
412 } /* while */
413 } /* difw > cn */
414 } /* bn > an */
415 else if (fb != 1) /* if fb == 1, the sticky bit is 1 (no possible carry) */
416 { /* b has entirely been read */
417 if (difw > cn)
418 { /* c has entirely been read */
419 if (rb < 0)
420 rb = 0;
421 fb = 0;
423 else if (diff_exp > aq2)
424 { /* b is followed by at least a zero bit, then by c */
425 if (rb < 0)
426 rb = 0;
427 fb = 1;
429 else
431 mp_size_t ck;
432 int difs;
434 MPFR_ASSERTD(difw >= 0 && cn >= difw);
435 ck = cn - difw;
436 difs = diff_exp % BITS_PER_MP_LIMB;
438 if (difs == 0 && ck == 0)
439 { /* c has entirely been read */
440 if (rb < 0)
441 rb = 0;
442 fb = 0;
444 else
446 mp_limb_t cc;
448 cc = difs ? (MPFR_ASSERTD(ck < cn),
449 cp[ck] << (BITS_PER_MP_LIMB - difs)) : cp[--ck];
450 if (rb < 0)
452 rb = cc >> (BITS_PER_MP_LIMB - 1);
453 cc &= ~MPFR_LIMB_HIGHBIT;
455 while (cc == 0)
457 if (ck == 0)
459 fb = 0;
460 goto rounding;
462 cc = cp[--ck];
463 } /* while */
464 fb = 1;
467 } /* fb != 1 */
469 rounding:
470 switch (rnd_mode)
472 case GMP_RNDN:
473 if (fb == 0)
475 if (rb == 0)
477 inex = 0;
478 goto set_exponent;
480 /* round to even */
481 if (ap[0] & (MPFR_LIMB_ONE << sh))
482 goto rndn_away;
483 else
484 goto rndn_zero;
486 if (rb == 0)
488 rndn_zero:
489 inex = MPFR_IS_NEG(a) ? 1 : -1;
490 goto set_exponent;
492 else
494 rndn_away:
495 inex = MPFR_IS_POS(a) ? 1 : -1;
496 goto add_one_ulp;
499 case GMP_RNDZ:
500 inex = rb || fb ? (MPFR_IS_NEG(a) ? 1 : -1) : 0;
501 goto set_exponent;
503 case GMP_RNDU:
504 inex = rb || fb;
505 if (inex && MPFR_IS_POS(a))
506 goto add_one_ulp;
507 else
508 goto set_exponent;
510 case GMP_RNDD:
511 inex = - (rb || fb);
512 if (inex && MPFR_IS_NEG(a))
513 goto add_one_ulp;
514 else
515 goto set_exponent;
517 default:
518 MPFR_ASSERTN(0);
519 inex = 0;
520 goto set_exponent;
523 add_one_ulp: /* add one unit in last place to a */
524 if (MPFR_UNLIKELY(mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh)))
526 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
528 inex = mpfr_overflow(a, rnd_mode, MPFR_SIGN(a));
529 goto end_of_add;
531 exp++;
532 ap[an-1] = MPFR_LIMB_HIGHBIT;
535 set_exponent:
536 MPFR_SET_EXP (a, exp);
538 end_of_add:
539 MPFR_TMP_FREE(marker);
540 MPFR_RET (inex);