beta-0.89.2
[luatex.git] / source / libs / mpfr / mpfr-3.1.3 / src / add1.c
blobb7b3094acab92af5e16a7f8430c7eac62c0384ff
1 /* mpfr_add1 -- internal function to perform a "real" addition
3 Copyright 1999-2015 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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 3 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.LESSER. If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "mpfr-impl.h"
25 /* compute sign(b) * (|b| + |c|), assuming b and c have same sign,
26 and are not NaN, Inf, nor zero. */
27 int
28 mpfr_add1 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
30 mp_limb_t *ap, *bp, *cp;
31 mpfr_prec_t aq, bq, cq, aq2;
32 mp_size_t an, bn, cn;
33 mpfr_exp_t difw, exp;
34 int sh, rb, fb, inex;
35 mpfr_uexp_t diff_exp;
36 MPFR_TMP_DECL(marker);
38 MPFR_ASSERTD(MPFR_IS_PURE_FP(b));
39 MPFR_ASSERTD(MPFR_IS_PURE_FP(c));
41 MPFR_TMP_MARK(marker);
43 aq = MPFR_PREC(a);
44 bq = MPFR_PREC(b);
45 cq = MPFR_PREC(c);
47 an = MPFR_PREC2LIMBS (aq); /* number of limbs of a */
48 aq2 = (mpfr_prec_t) an * GMP_NUMB_BITS;
49 sh = aq2 - aq; /* non-significant bits in low limb */
51 bn = MPFR_PREC2LIMBS (bq); /* number of limbs of b */
52 cn = MPFR_PREC2LIMBS (cq); /* number of limbs of c */
54 ap = MPFR_MANT(a);
55 bp = MPFR_MANT(b);
56 cp = MPFR_MANT(c);
58 if (MPFR_UNLIKELY(ap == bp))
60 bp = MPFR_TMP_LIMBS_ALLOC (bn);
61 MPN_COPY (bp, ap, bn);
62 if (ap == cp)
63 { cp = bp; }
65 else if (MPFR_UNLIKELY(ap == cp))
67 cp = MPFR_TMP_LIMBS_ALLOC (cn);
68 MPN_COPY(cp, ap, cn);
71 exp = MPFR_GET_EXP (b);
72 MPFR_SET_SAME_SIGN(a, b);
73 MPFR_UPDATE2_RND_MODE(rnd_mode, MPFR_SIGN(b));
74 /* now rnd_mode is either MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
75 /* Note: exponents can be negative, but the unsigned subtraction is
76 a modular subtraction, so that one gets the correct result. */
77 diff_exp = (mpfr_uexp_t) exp - MPFR_GET_EXP(c);
80 * 1. Compute the significant part A', the non-significant bits of A
81 * are taken into account.
83 * 2. Perform the rounding. At each iteration, we remember:
84 * _ r = rounding bit
85 * _ f = following bits (same value)
86 * where the result has the form: [number A]rfff...fff + a remaining
87 * value in the interval [0,2) ulp. We consider the most significant
88 * bits of the remaining value to update the result; a possible carry
89 * is immediately taken into account and A is updated accordingly. As
90 * soon as the bits f don't have the same value, A can be rounded.
91 * Variables:
92 * _ rb = rounding bit (0 or 1).
93 * _ fb = following bits (0 or 1), then sticky bit.
94 * If fb == 0, the only thing that can change is the sticky bit.
97 rb = fb = -1; /* means: not initialized */
99 if (MPFR_UNLIKELY (MPFR_UEXP (aq2) <= diff_exp))
100 { /* c does not overlap with a' */
101 if (MPFR_UNLIKELY(an > bn))
102 { /* a has more limbs than b */
103 /* copy b to the most significant limbs of a */
104 MPN_COPY(ap + (an - bn), bp, bn);
105 /* zero the least significant limbs of a */
106 MPN_ZERO(ap, an - bn);
108 else /* an <= bn */
110 /* copy the most significant limbs of b to a */
111 MPN_COPY(ap, bp + (bn - an), an);
114 else /* aq2 > diff_exp */
115 { /* c overlaps with a' */
116 mp_limb_t *a2p;
117 mp_limb_t cc;
118 mpfr_prec_t dif;
119 mp_size_t difn, k;
120 int shift;
122 /* copy c (shifted) into a */
124 dif = aq2 - diff_exp;
125 /* dif is the number of bits of c which overlap with a' */
127 difn = MPFR_PREC2LIMBS (dif);
128 /* only the highest difn limbs from c have to be considered */
129 if (MPFR_UNLIKELY(difn > cn))
131 /* c doesn't have enough limbs; take into account the virtual
132 zero limbs now by zeroing the least significant limbs of a' */
133 MPFR_ASSERTD(difn - cn <= an);
134 MPN_ZERO(ap, difn - cn);
135 difn = cn;
137 k = diff_exp / GMP_NUMB_BITS;
139 /* zero the most significant k limbs of a */
140 a2p = ap + (an - k);
141 MPN_ZERO(a2p, k);
143 shift = diff_exp % GMP_NUMB_BITS;
145 if (MPFR_LIKELY(shift))
147 MPFR_ASSERTD(a2p - difn >= ap);
148 cc = mpn_rshift(a2p - difn, cp + (cn - difn), difn, shift);
149 if (MPFR_UNLIKELY(a2p - difn > ap))
150 *(a2p - difn - 1) = cc;
152 else
153 MPN_COPY(a2p - difn, cp + (cn - difn), difn);
155 /* add b to a */
156 cc = MPFR_UNLIKELY(an > bn)
157 ? mpn_add_n(ap + (an - bn), ap + (an - bn), bp, bn)
158 : mpn_add_n(ap, ap, bp + (bn - an), an);
160 if (MPFR_UNLIKELY(cc)) /* carry */
162 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
164 inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
165 goto end_of_add;
167 exp++;
168 rb = (ap[0] >> sh) & 1; /* LSB(a) --> rounding bit after the shift */
169 if (MPFR_LIKELY(sh))
171 mp_limb_t mask, bb;
173 mask = MPFR_LIMB_MASK (sh);
174 bb = ap[0] & mask;
175 ap[0] &= (~mask) << 1;
176 if (bb == 0)
177 fb = 0;
178 else if (bb == mask)
179 fb = 1;
181 mpn_rshift(ap, ap, an, 1);
182 ap[an-1] += MPFR_LIMB_HIGHBIT;
183 if (sh && fb < 0)
184 goto rounding;
185 } /* cc */
186 } /* aq2 > diff_exp */
188 /* non-significant bits of a */
189 if (MPFR_LIKELY(rb < 0 && sh))
191 mp_limb_t mask, bb;
193 mask = MPFR_LIMB_MASK (sh);
194 bb = ap[0] & mask;
195 ap[0] &= ~mask;
196 rb = bb >> (sh - 1);
197 if (MPFR_LIKELY(sh > 1))
199 mask >>= 1;
200 bb &= mask;
201 if (bb == 0)
202 fb = 0;
203 else if (bb == mask)
204 fb = 1;
205 else
206 goto rounding;
210 /* determine rounding and sticky bits (and possible carry) */
212 difw = (mpfr_exp_t) an - (mpfr_exp_t) (diff_exp / GMP_NUMB_BITS);
213 /* difw is the number of limbs from b (regarded as having an infinite
214 precision) that have already been combined with c; -n if the next
215 n limbs from b won't be combined with c. */
217 if (MPFR_UNLIKELY(bn > an))
218 { /* there are still limbs from b that haven't been taken into account */
219 mp_size_t bk;
221 if (fb == 0 && difw <= 0)
223 fb = 1; /* c hasn't been taken into account ==> sticky bit != 0 */
224 goto rounding;
227 bk = bn - an; /* index of lowest considered limb from b, > 0 */
228 while (difw < 0)
229 { /* ulp(next limb from b) > msb(c) */
230 mp_limb_t bb;
232 bb = bp[--bk];
234 MPFR_ASSERTD(fb != 0);
235 if (fb > 0)
237 if (bb != MP_LIMB_T_MAX)
239 fb = 1; /* c hasn't been taken into account
240 ==> sticky bit != 0 */
241 goto rounding;
244 else /* fb not initialized yet */
246 if (rb < 0) /* rb not initialized yet */
248 rb = bb >> (GMP_NUMB_BITS - 1);
249 bb |= MPFR_LIMB_HIGHBIT;
251 fb = 1;
252 if (bb != MP_LIMB_T_MAX)
253 goto rounding;
256 if (bk == 0)
257 { /* b has entirely been read */
258 fb = 1; /* c hasn't been taken into account
259 ==> sticky bit != 0 */
260 goto rounding;
263 difw++;
264 } /* while */
265 MPFR_ASSERTD(bk > 0 && difw >= 0);
267 if (difw <= cn)
269 mp_size_t ck;
270 mp_limb_t cprev;
271 int difs;
273 ck = cn - difw;
274 difs = diff_exp % GMP_NUMB_BITS;
276 if (difs == 0 && ck == 0)
277 goto c_read;
279 cprev = ck == cn ? 0 : cp[ck];
281 if (fb < 0)
283 mp_limb_t bb, cc;
285 if (difs)
287 cc = cprev << (GMP_NUMB_BITS - difs);
288 if (--ck >= 0)
290 cprev = cp[ck];
291 cc += cprev >> difs;
294 else
295 cc = cp[--ck];
297 bb = bp[--bk] + cc;
299 if (bb < cc /* carry */
300 && (rb < 0 || (rb ^= 1) == 0)
301 && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
303 if (exp == __gmpfr_emax)
305 inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
306 goto end_of_add;
308 exp++;
309 ap[an-1] = MPFR_LIMB_HIGHBIT;
310 rb = 0;
313 if (rb < 0) /* rb not initialized yet */
315 rb = bb >> (GMP_NUMB_BITS - 1);
316 bb <<= 1;
317 bb |= bb >> (GMP_NUMB_BITS - 1);
320 fb = bb != 0;
321 if (fb && bb != MP_LIMB_T_MAX)
322 goto rounding;
323 } /* fb < 0 */
325 while (bk > 0)
327 mp_limb_t bb, cc;
329 if (difs)
331 if (ck < 0)
332 goto c_read;
333 cc = cprev << (GMP_NUMB_BITS - difs);
334 if (--ck >= 0)
336 cprev = cp[ck];
337 cc += cprev >> difs;
340 else
342 if (ck == 0)
343 goto c_read;
344 cc = cp[--ck];
347 bb = bp[--bk] + cc;
348 if (bb < cc) /* carry */
350 fb ^= 1;
351 if (fb)
352 goto rounding;
353 rb ^= 1;
354 if (rb == 0 && mpn_add_1(ap, ap, an, MPFR_LIMB_ONE << sh))
356 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
358 inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
359 goto end_of_add;
361 exp++;
362 ap[an-1] = MPFR_LIMB_HIGHBIT;
364 } /* bb < cc */
366 if (!fb && bb != 0)
368 fb = 1;
369 goto rounding;
371 if (fb && bb != MP_LIMB_T_MAX)
372 goto rounding;
373 } /* while */
375 /* b has entirely been read */
377 if (fb || ck < 0)
378 goto rounding;
379 if (difs && cprev << (GMP_NUMB_BITS - difs))
381 fb = 1;
382 goto rounding;
384 while (ck)
386 if (cp[--ck])
388 fb = 1;
389 goto rounding;
391 } /* while */
392 } /* difw <= cn */
393 else
394 { /* c has entirely been read */
395 c_read:
396 if (fb < 0) /* fb not initialized yet */
398 mp_limb_t bb;
400 MPFR_ASSERTD(bk > 0);
401 bb = bp[--bk];
402 if (rb < 0) /* rb not initialized yet */
404 rb = bb >> (GMP_NUMB_BITS - 1);
405 bb &= ~MPFR_LIMB_HIGHBIT;
407 fb = bb != 0;
408 } /* fb < 0 */
409 if (fb)
410 goto rounding;
411 while (bk)
413 if (bp[--bk])
415 fb = 1;
416 goto rounding;
418 } /* while */
419 } /* difw > cn */
420 } /* bn > an */
421 else if (fb != 1) /* if fb == 1, the sticky bit is 1 (no possible carry) */
422 { /* b has entirely been read */
423 if (difw > cn)
424 { /* c has entirely been read */
425 if (rb < 0)
426 rb = 0;
427 fb = 0;
429 else if (diff_exp > MPFR_UEXP (aq2))
430 { /* b is followed by at least a zero bit, then by c */
431 if (rb < 0)
432 rb = 0;
433 fb = 1;
435 else
437 mp_size_t ck;
438 int difs;
440 MPFR_ASSERTD(difw >= 0 && cn >= difw);
441 ck = cn - difw;
442 difs = diff_exp % GMP_NUMB_BITS;
444 if (difs == 0 && ck == 0)
445 { /* c has entirely been read */
446 if (rb < 0)
447 rb = 0;
448 fb = 0;
450 else
452 mp_limb_t cc;
454 cc = difs ? (MPFR_ASSERTD(ck < cn),
455 cp[ck] << (GMP_NUMB_BITS - difs)) : cp[--ck];
456 if (rb < 0)
458 rb = cc >> (GMP_NUMB_BITS - 1);
459 cc &= ~MPFR_LIMB_HIGHBIT;
461 while (cc == 0)
463 if (ck == 0)
465 fb = 0;
466 goto rounding;
468 cc = cp[--ck];
469 } /* while */
470 fb = 1;
473 } /* fb != 1 */
475 rounding:
476 /* rnd_mode should be one of MPFR_RNDN, MPFR_RNDZ or MPFR_RNDA */
477 if (MPFR_LIKELY(rnd_mode == MPFR_RNDN))
479 if (fb == 0)
481 if (rb == 0)
483 inex = 0;
484 goto set_exponent;
486 /* round to even */
487 if (ap[0] & (MPFR_LIMB_ONE << sh))
488 goto rndn_away;
489 else
490 goto rndn_zero;
492 if (rb == 0)
494 rndn_zero:
495 inex = MPFR_IS_NEG(a) ? 1 : -1;
496 goto set_exponent;
498 else
500 rndn_away:
501 inex = MPFR_IS_POS(a) ? 1 : -1;
502 goto add_one_ulp;
505 else if (rnd_mode == MPFR_RNDZ)
507 inex = rb || fb ? (MPFR_IS_NEG(a) ? 1 : -1) : 0;
508 goto set_exponent;
510 else
512 MPFR_ASSERTN (rnd_mode == MPFR_RNDA);
513 inex = rb || fb ? (MPFR_IS_POS(a) ? 1 : -1) : 0;
514 if (inex)
515 goto add_one_ulp;
516 else
517 goto set_exponent;
520 add_one_ulp: /* add one unit in last place to a */
521 if (MPFR_UNLIKELY(mpn_add_1 (ap, ap, an, MPFR_LIMB_ONE << sh)))
523 if (MPFR_UNLIKELY(exp == __gmpfr_emax))
525 inex = mpfr_overflow (a, rnd_mode, MPFR_SIGN(a));
526 goto end_of_add;
528 exp++;
529 ap[an-1] = MPFR_LIMB_HIGHBIT;
532 set_exponent:
533 MPFR_SET_EXP (a, exp);
535 end_of_add:
536 MPFR_TMP_FREE(marker);
537 MPFR_RET (inex);