kernel - Reenable acpi sleep states
[dragonfly.git] / contrib / mpfr / sub1sp.c
blobe3412df605be10e62de1d207579307486626a78b
1 /* mpfr_sub1sp -- internal function to perform a "real" substraction
2 All the op must have the same precision
4 Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by the Arenaire and Cacao projects, INRIA.
7 This file is part of the GNU MPFR Library.
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or (at your
12 option) any later version.
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LIB. If not, write to
21 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #define MPFR_NEED_LONGLONG_H
25 #include "mpfr-impl.h"
27 /* Check if we have to check the result of mpfr_sub1sp with mpfr_sub1 */
28 #ifdef WANT_ASSERT
29 # if WANT_ASSERT >= 2
31 int mpfr_sub1sp2 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode);
32 int mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
34 mpfr_t tmpa, tmpb, tmpc;
35 int inexb, inexc, inexact, inexact2;
37 mpfr_init2 (tmpa, MPFR_PREC (a));
38 mpfr_init2 (tmpb, MPFR_PREC (b));
39 mpfr_init2 (tmpc, MPFR_PREC (c));
41 inexb = mpfr_set (tmpb, b, GMP_RNDN);
42 MPFR_ASSERTN (inexb == 0);
44 inexc = mpfr_set (tmpc, c, GMP_RNDN);
45 MPFR_ASSERTN (inexc == 0);
47 inexact2 = mpfr_sub1 (tmpa, tmpb, tmpc, rnd_mode);
48 inexact = mpfr_sub1sp2(a, b, c, rnd_mode);
50 if (mpfr_cmp (tmpa, a) || inexact != inexact2)
52 fprintf (stderr, "sub1 & sub1sp return different values for %s\n"
53 "Prec_a = %lu, Prec_b = %lu, Prec_c = %lu\nB = ",
54 mpfr_print_rnd_mode (rnd_mode), (unsigned long) MPFR_PREC (a),
55 (unsigned long) MPFR_PREC (b), (unsigned long) MPFR_PREC (c));
56 mpfr_fprint_binary (stderr, tmpb);
57 fprintf (stderr, "\nC = ");
58 mpfr_fprint_binary (stderr, tmpc);
59 fprintf (stderr, "\nSub1 : ");
60 mpfr_fprint_binary (stderr, tmpa);
61 fprintf (stderr, "\nSub1sp: ");
62 mpfr_fprint_binary (stderr, a);
63 fprintf (stderr, "\nInexact sp = %d | Inexact = %d\n",
64 inexact, inexact2);
65 MPFR_ASSERTN (0);
67 mpfr_clears (tmpa, tmpb, tmpc, (mpfr_ptr) 0);
68 return inexact;
70 # define mpfr_sub1sp mpfr_sub1sp2
71 # endif
72 #endif
74 /* Debugging support */
75 #ifdef DEBUG
76 # undef DEBUG
77 # define DEBUG(x) (x)
78 #else
79 # define DEBUG(x) /**/
80 #endif
82 /* Rounding Sub */
85 compute sgn(b)*(|b| - |c|) if |b|>|c| else -sgn(b)*(|c| -|b|)
86 Returns 0 iff result is exact,
87 a negative value when the result is less than the exact value,
88 a positive value otherwise.
91 /* A0...Ap-1
92 * Cp Cp+1 ....
93 * <- C'p+1 ->
94 * Cp = -1 if calculated from c mantissa
95 * Cp = 0 if 0 from a or c
96 * Cp = 1 if calculated from a.
97 * C'p+1 = First bit not null or 0 if there isn't one
99 * Can't have Cp=-1 and C'p+1=1*/
101 /* RND = GMP_RNDZ:
102 * + if Cp=0 and C'p+1=0,1, Truncate.
103 * + if Cp=0 and C'p+1=-1, SubOneUlp
104 * + if Cp=-1, SubOneUlp
105 * + if Cp=1, AddOneUlp
106 * RND = GMP_RNDA (Away)
107 * + if Cp=0 and C'p+1=0,-1, Truncate
108 * + if Cp=0 and C'p+1=1, AddOneUlp
109 * + if Cp=1, AddOneUlp
110 * + if Cp=-1, Truncate
111 * RND = GMP_RNDN
112 * + if Cp=0, Truncate
113 * + if Cp=1 and C'p+1=1, AddOneUlp
114 * + if Cp=1 and C'p+1=-1, Truncate
115 * + if Cp=1 and C'p+1=0, Truncate if Ap-1=0, AddOneUlp else
116 * + if Cp=-1 and C'p+1=-1, SubOneUlp
117 * + if Cp=-1 and C'p+1=0, Truncate if Ap-1=0, SubOneUlp else
119 * If AddOneUlp:
120 * If carry, then it is 11111111111 + 1 = 10000000000000
121 * ap[n-1]=MPFR_HIGHT_BIT
122 * If SubOneUlp:
123 * If we lose one bit, it is 1000000000 - 1 = 0111111111111
124 * Then shift, and put as last bit x which is calculated
125 * according Cp, Cp-1 and rnd_mode.
126 * If Truncate,
127 * If it is a power of 2,
128 * we may have to suboneulp in some special cases.
130 * To simplify, we don't use Cp = 1.
135 mpfr_sub1sp (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
137 mp_exp_t bx,cx;
138 mp_exp_unsigned_t d;
139 mp_prec_t p, sh, cnt;
140 mp_size_t n;
141 mp_limb_t *ap, *bp, *cp;
142 mp_limb_t limb;
143 int inexact;
144 mp_limb_t bcp,bcp1; /* Cp and C'p+1 */
145 mp_limb_t bbcp = (mp_limb_t) -1, bbcp1 = (mp_limb_t) -1; /* Cp+1 and C'p+2,
146 gcc claims that they might be used uninitialized. We fill them with invalid
147 values, which should produce a failure if so. See README.dev file. */
149 MPFR_TMP_DECL(marker);
151 MPFR_TMP_MARK(marker);
153 MPFR_ASSERTD(MPFR_PREC(a) == MPFR_PREC(b) && MPFR_PREC(b) == MPFR_PREC(c));
154 MPFR_ASSERTD(MPFR_IS_PURE_FP(b) && MPFR_IS_PURE_FP(c));
156 /* Read prec and num of limbs */
157 p = MPFR_PREC(b);
158 n = (p-1)/BITS_PER_MP_LIMB+1;
160 /* Fast cmp of |b| and |c|*/
161 bx = MPFR_GET_EXP (b);
162 cx = MPFR_GET_EXP (c);
163 if (MPFR_UNLIKELY(bx == cx))
165 mp_size_t k = n - 1;
166 /* Check mantissa since exponent are equals */
167 bp = MPFR_MANT(b);
168 cp = MPFR_MANT(c);
169 while (k>=0 && MPFR_UNLIKELY(bp[k] == cp[k]))
170 k--;
171 if (MPFR_UNLIKELY(k < 0))
172 /* b == c ! */
174 /* Return exact number 0 */
175 if (rnd_mode == GMP_RNDD)
176 MPFR_SET_NEG(a);
177 else
178 MPFR_SET_POS(a);
179 MPFR_SET_ZERO(a);
180 MPFR_RET(0);
182 else if (bp[k] > cp[k])
183 goto BGreater;
184 else
186 MPFR_ASSERTD(bp[k]<cp[k]);
187 goto CGreater;
190 else if (MPFR_UNLIKELY(bx < cx))
192 /* Swap b and c and set sign */
193 mpfr_srcptr t;
194 mp_exp_t tx;
195 CGreater:
196 MPFR_SET_OPPOSITE_SIGN(a,b);
197 t = b; b = c; c = t;
198 tx = bx; bx = cx; cx = tx;
200 else
202 /* b > c */
203 BGreater:
204 MPFR_SET_SAME_SIGN(a,b);
207 /* Now b > c */
208 MPFR_ASSERTD(bx >= cx);
209 d = (mp_exp_unsigned_t) bx - cx;
210 DEBUG (printf ("New with diff=%lu\n", (unsigned long) d));
212 if (MPFR_UNLIKELY(d <= 1))
214 if (MPFR_LIKELY(d < 1))
216 /* <-- b -->
217 <-- c --> : exact sub */
218 ap = MPFR_MANT(a);
219 mpn_sub_n (ap, MPFR_MANT(b), MPFR_MANT(c), n);
220 /* Normalize */
221 ExactNormalize:
222 limb = ap[n-1];
223 if (MPFR_LIKELY(limb))
225 /* First limb is not zero. */
226 count_leading_zeros(cnt, limb);
227 /* cnt could be == 0 <= SubD1Lose */
228 if (MPFR_LIKELY(cnt))
230 mpn_lshift(ap, ap, n, cnt); /* Normalize number */
231 bx -= cnt; /* Update final expo */
233 /* Last limb should be ok */
234 MPFR_ASSERTD(!(ap[0] & MPFR_LIMB_MASK((-p)%BITS_PER_MP_LIMB)));
236 else
238 /* First limb is zero */
239 mp_size_t k = n-1, len;
240 /* Find the first limb not equal to zero.
241 FIXME:It is assume it exists (since |b| > |c| and same prec)*/
244 MPFR_ASSERTD( k > 0 );
245 limb = ap[--k];
247 while (limb == 0);
248 MPFR_ASSERTD(limb != 0);
249 count_leading_zeros(cnt, limb);
250 k++;
251 len = n - k; /* Number of last limb */
252 MPFR_ASSERTD(k >= 0);
253 if (MPFR_LIKELY(cnt))
254 mpn_lshift(ap+len, ap, k, cnt); /* Normalize the High Limb*/
255 else
257 /* Must use DECR since src and dest may overlap & dest>=src*/
258 MPN_COPY_DECR(ap+len, ap, k);
260 MPN_ZERO(ap, len); /* Zeroing the last limbs */
261 bx -= cnt + len*BITS_PER_MP_LIMB; /* Update Expo */
262 /* Last limb should be ok */
263 MPFR_ASSERTD(!(ap[len]&MPFR_LIMB_MASK((-p)%BITS_PER_MP_LIMB)));
265 /* Check expo underflow */
266 if (MPFR_UNLIKELY(bx < __gmpfr_emin))
268 MPFR_TMP_FREE(marker);
269 /* inexact=0 */
270 DEBUG( printf("(D==0 Underflow)\n") );
271 if (rnd_mode == GMP_RNDN &&
272 (bx < __gmpfr_emin - 1 ||
273 (/*inexact >= 0 &&*/ mpfr_powerof2_raw (a))))
274 rnd_mode = GMP_RNDZ;
275 return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
277 MPFR_SET_EXP (a, bx);
278 /* No rounding is necessary since the result is exact */
279 MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
280 MPFR_TMP_FREE(marker);
281 return 0;
283 else /* if (d == 1) */
285 /* | <-- b -->
286 | <-- c --> */
287 mp_limb_t c0, mask;
288 mp_size_t k;
289 MPFR_UNSIGNED_MINUS_MODULO(sh, p);
290 /* If we lose at least one bit, compute 2*b-c (Exact)
291 * else compute b-c/2 */
292 bp = MPFR_MANT(b);
293 cp = MPFR_MANT(c);
294 k = n-1;
295 limb = bp[k] - cp[k]/2;
296 if (limb > MPFR_LIMB_HIGHBIT)
298 /* We can't lose precision: compute b-c/2 */
299 /* Shift c in the allocated temporary block */
300 SubD1NoLose:
301 c0 = cp[0] & (MPFR_LIMB_ONE<<sh);
302 cp = (mp_limb_t*) MPFR_TMP_ALLOC(n * BYTES_PER_MP_LIMB);
303 mpn_rshift(cp, MPFR_MANT(c), n, 1);
304 if (MPFR_LIKELY(c0 == 0))
306 /* Result is exact: no need of rounding! */
307 ap = MPFR_MANT(a);
308 mpn_sub_n (ap, bp, cp, n);
309 MPFR_SET_EXP(a, bx); /* No expo overflow! */
310 /* No truncate or normalize is needed */
311 MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
312 /* No rounding is necessary since the result is exact */
313 MPFR_TMP_FREE(marker);
314 return 0;
316 ap = MPFR_MANT(a);
317 mask = ~MPFR_LIMB_MASK(sh);
318 cp[0] &= mask; /* Delete last bit of c */
319 mpn_sub_n (ap, bp, cp, n);
320 MPFR_SET_EXP(a, bx); /* No expo overflow! */
321 MPFR_ASSERTD( !(ap[0] & ~mask) ); /* Check last bits */
322 /* No normalize is needed */
323 MPFR_ASSERTD(ap[n-1] > ~ap[n-1]);
324 /* Rounding is necessary since c0 = 1*/
325 /* Cp =-1 and C'p+1=0 */
326 bcp = 1; bcp1 = 0;
327 if (MPFR_LIKELY(rnd_mode == GMP_RNDN))
329 /* Even Rule apply: Check Ap-1 */
330 if (MPFR_LIKELY( (ap[0] & (MPFR_LIMB_ONE<<sh)) == 0) )
331 goto truncate;
332 else
333 goto sub_one_ulp;
335 MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
336 if (rnd_mode == GMP_RNDZ)
337 goto sub_one_ulp;
338 else
339 goto truncate;
341 else if (MPFR_LIKELY(limb < MPFR_LIMB_HIGHBIT))
343 /* We lose at least one bit of prec */
344 /* Calcul of 2*b-c (Exact) */
345 /* Shift b in the allocated temporary block */
346 SubD1Lose:
347 bp = (mp_limb_t*) MPFR_TMP_ALLOC (n * BYTES_PER_MP_LIMB);
348 mpn_lshift (bp, MPFR_MANT(b), n, 1);
349 ap = MPFR_MANT(a);
350 mpn_sub_n (ap, bp, cp, n);
351 bx--;
352 goto ExactNormalize;
354 else
356 /* Case: limb = 100000000000 */
357 /* Check while b[k] == c'[k] (C' is C shifted by 1) */
358 /* If b[k]<c'[k] => We lose at least one bit*/
359 /* If b[k]>c'[k] => We don't lose any bit */
360 /* If k==-1 => We don't lose any bit
361 AND the result is 100000000000 0000000000 00000000000 */
362 mp_limb_t carry;
363 do {
364 carry = cp[k]&MPFR_LIMB_ONE;
365 k--;
366 } while (k>=0 &&
367 bp[k]==(carry=cp[k]/2+(carry<<(BITS_PER_MP_LIMB-1))));
368 if (MPFR_UNLIKELY(k<0))
370 /*If carry then (sh==0 and Virtual c'[-1] > Virtual b[-1]) */
371 if (MPFR_UNLIKELY(carry)) /* carry = cp[0]&MPFR_LIMB_ONE */
373 /* FIXME: Can be faster? */
374 MPFR_ASSERTD(sh == 0);
375 goto SubD1Lose;
377 /* Result is a power of 2 */
378 ap = MPFR_MANT (a);
379 MPN_ZERO (ap, n);
380 ap[n-1] = MPFR_LIMB_HIGHBIT;
381 MPFR_SET_EXP (a, bx); /* No expo overflow! */
382 /* No Normalize is needed*/
383 /* No Rounding is needed */
384 MPFR_TMP_FREE (marker);
385 return 0;
387 /* carry = cp[k]/2+(cp[k-1]&1)<<(BITS_PER_MP_LIMB-1) = c'[k]*/
388 else if (bp[k] > carry)
389 goto SubD1NoLose;
390 else
392 MPFR_ASSERTD(bp[k]<carry);
393 goto SubD1Lose;
398 else if (MPFR_UNLIKELY(d >= p))
400 ap = MPFR_MANT(a);
401 MPFR_UNSIGNED_MINUS_MODULO(sh, p);
402 /* We can't set A before since we use cp for rounding... */
403 /* Perform rounding: check if a=b or a=b-ulp(b) */
404 if (MPFR_UNLIKELY(d == p))
406 /* cp == -1 and c'p+1 = ? */
407 bcp = 1;
408 /* We need Cp+1 later for a very improbable case. */
409 bbcp = (MPFR_MANT(c)[n-1] & (MPFR_LIMB_ONE<<(BITS_PER_MP_LIMB-2)));
410 /* We need also C'p+1 for an even more unprobable case... */
411 if (MPFR_LIKELY( bbcp ))
412 bcp1 = 1;
413 else
415 cp = MPFR_MANT(c);
416 if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
418 mp_size_t k = n-1;
419 do {
420 k--;
421 } while (k>=0 && cp[k]==0);
422 bcp1 = (k>=0);
424 else
425 bcp1 = 1;
427 DEBUG( printf("(D=P) Cp=-1 Cp+1=%d C'p+1=%d \n", bbcp!=0, bcp1!=0) );
428 bp = MPFR_MANT (b);
430 /* Even if src and dest overlap, it is ok using MPN_COPY */
431 if (MPFR_LIKELY(rnd_mode == GMP_RNDN))
433 if (MPFR_UNLIKELY( bcp && bcp1==0 ))
434 /* Cp=-1 and C'p+1=0: Even rule Apply! */
435 /* Check Ap-1 = Bp-1 */
436 if ((bp[0] & (MPFR_LIMB_ONE<<sh)) == 0)
438 MPN_COPY(ap, bp, n);
439 goto truncate;
441 MPN_COPY(ap, bp, n);
442 goto sub_one_ulp;
444 MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
445 if (rnd_mode == GMP_RNDZ)
447 MPN_COPY(ap, bp, n);
448 goto sub_one_ulp;
450 else
452 MPN_COPY(ap, bp, n);
453 goto truncate;
456 else
458 /* Cp=0, Cp+1=-1 if d==p+1, C'p+1=-1 */
459 bcp = 0; bbcp = (d==p+1); bcp1 = 1;
460 DEBUG( printf("(D>P) Cp=%d Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0) );
461 /* Need to compute C'p+2 if d==p+1 and if rnd_mode=NEAREST
462 (Because of a very improbable case) */
463 if (MPFR_UNLIKELY(d==p+1 && rnd_mode==GMP_RNDN))
465 cp = MPFR_MANT(c);
466 if (MPFR_UNLIKELY(cp[n-1] == MPFR_LIMB_HIGHBIT))
468 mp_size_t k = n-1;
469 do {
470 k--;
471 } while (k>=0 && cp[k]==0);
472 bbcp1 = (k>=0);
474 else
475 bbcp1 = 1;
476 DEBUG( printf("(D>P) C'p+2=%d\n", bbcp1!=0) );
478 /* Copy mantissa B in A */
479 MPN_COPY(ap, MPFR_MANT(b), n);
480 /* Round */
481 if (MPFR_LIKELY(rnd_mode == GMP_RNDN))
482 goto truncate;
483 MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
484 if (rnd_mode == GMP_RNDZ)
485 goto sub_one_ulp;
486 else /* rnd_mode = AWAY */
487 goto truncate;
490 else
492 mp_exp_unsigned_t dm;
493 mp_size_t m;
494 mp_limb_t mask;
496 /* General case: 2 <= d < p */
497 MPFR_UNSIGNED_MINUS_MODULO(sh, p);
498 cp = (mp_limb_t*) MPFR_TMP_ALLOC(n * BYTES_PER_MP_LIMB);
500 /* Shift c in temporary allocated place */
501 dm = d % BITS_PER_MP_LIMB;
502 m = d / BITS_PER_MP_LIMB;
503 if (MPFR_UNLIKELY(dm == 0))
505 /* dm = 0 and m > 0: Just copy */
506 MPFR_ASSERTD(m!=0);
507 MPN_COPY(cp, MPFR_MANT(c)+m, n-m);
508 MPN_ZERO(cp+n-m, m);
510 else if (MPFR_LIKELY(m == 0))
512 /* dm >=2 and m == 0: just shift */
513 MPFR_ASSERTD(dm >= 2);
514 mpn_rshift(cp, MPFR_MANT(c), n, dm);
516 else
518 /* dm > 0 and m > 0: shift and zero */
519 mpn_rshift(cp, MPFR_MANT(c)+m, n-m, dm);
520 MPN_ZERO(cp+n-m, m);
523 DEBUG( mpfr_print_mant_binary("Before", MPFR_MANT(c), p) );
524 DEBUG( mpfr_print_mant_binary("B= ", MPFR_MANT(b), p) );
525 DEBUG( mpfr_print_mant_binary("After ", cp, p) );
527 /* Compute bcp=Cp and bcp1=C'p+1 */
528 if (MPFR_LIKELY(sh))
530 /* Try to compute them from C' rather than C (FIXME: Faster?) */
531 bcp = (cp[0] & (MPFR_LIMB_ONE<<(sh-1))) ;
532 if (MPFR_LIKELY( cp[0] & MPFR_LIMB_MASK(sh-1) ))
533 bcp1 = 1;
534 else
536 /* We can't compute C'p+1 from C'. Compute it from C */
537 /* Start from bit x=p-d+sh in mantissa C
538 (+sh since we have already looked sh bits in C'!) */
539 mpfr_prec_t x = p-d+sh-1;
540 if (MPFR_LIKELY(x>p))
541 /* We are already looked at all the bits of c, so C'p+1 = 0*/
542 bcp1 = 0;
543 else
545 mp_limb_t *tp = MPFR_MANT(c);
546 mp_size_t kx = n-1 - (x / BITS_PER_MP_LIMB);
547 mpfr_prec_t sx = BITS_PER_MP_LIMB-1-(x%BITS_PER_MP_LIMB);
548 DEBUG (printf ("(First) x=%lu Kx=%ld Sx=%lu\n",
549 (unsigned long) x, (long) kx,
550 (unsigned long) sx));
551 /* Looks at the last bits of limb kx (if sx=0 does nothing)*/
552 if (tp[kx] & MPFR_LIMB_MASK(sx))
553 bcp1 = 1;
554 else
556 /*kx += (sx==0);*/
557 /*If sx==0, tp[kx] hasn't been checked*/
558 do {
559 kx--;
560 } while (kx>=0 && tp[kx]==0);
561 bcp1 = (kx >= 0);
566 else
568 /* Compute Cp and C'p+1 from C with sh=0 */
569 mp_limb_t *tp = MPFR_MANT(c);
570 /* Start from bit x=p-d in mantissa C */
571 mpfr_prec_t x = p-d;
572 mp_size_t kx = n-1 - (x / BITS_PER_MP_LIMB);
573 mpfr_prec_t sx = BITS_PER_MP_LIMB-1-(x%BITS_PER_MP_LIMB);
574 MPFR_ASSERTD(p >= d);
575 bcp = (tp[kx] & (MPFR_LIMB_ONE<<sx));
576 /* Looks at the last bits of limb kx (If sx=0, does nothing)*/
577 if (tp[kx] & MPFR_LIMB_MASK(sx))
578 bcp1 = 1;
579 else
581 /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
582 do {
583 kx--;
584 } while (kx>=0 && tp[kx]==0);
585 bcp1 = (kx>=0);
588 DEBUG( printf("sh=%lu Cp=%d C'p+1=%d\n", sh, bcp!=0, bcp1!=0) );
590 /* Check if we can lose a bit, and if so compute Cp+1 and C'p+2 */
591 bp = MPFR_MANT(b);
592 if (MPFR_UNLIKELY((bp[n-1]-cp[n-1]) <= MPFR_LIMB_HIGHBIT))
594 /* We can lose a bit so we precompute Cp+1 and C'p+2 */
595 /* Test for trivial case: since C'p+1=0, Cp+1=0 and C'p+2 =0 */
596 if (MPFR_LIKELY(bcp1 == 0))
598 bbcp = 0;
599 bbcp1 = 0;
601 else /* bcp1 != 0 */
603 /* We can lose a bit:
604 compute Cp+1 and C'p+2 from mantissa C */
605 mp_limb_t *tp = MPFR_MANT(c);
606 /* Start from bit x=(p+1)-d in mantissa C */
607 mp_prec_t x = p+1-d;
608 mp_size_t kx = n-1 - (x/BITS_PER_MP_LIMB);
609 mp_prec_t sx = BITS_PER_MP_LIMB-1-(x%BITS_PER_MP_LIMB);
610 MPFR_ASSERTD(p > d);
611 DEBUG (printf ("(pre) x=%lu Kx=%ld Sx=%lu\n",
612 (unsigned long) x, (long) kx,
613 (unsigned long) sx));
614 bbcp = (tp[kx] & (MPFR_LIMB_ONE<<sx)) ;
615 /* Looks at the last bits of limb kx (If sx=0, does nothing)*/
616 /* If Cp+1=0, since C'p+1!=0, C'p+2=1 ! */
617 if (MPFR_LIKELY(bbcp==0 || (tp[kx]&MPFR_LIMB_MASK(sx))))
618 bbcp1 = 1;
619 else
621 /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
622 do {
623 kx--;
624 } while (kx>=0 && tp[kx]==0);
625 bbcp1 = (kx>=0);
626 DEBUG (printf ("(Pre) Scan done for %ld\n", (long) kx));
628 } /*End of Bcp1 != 0*/
629 DEBUG( printf("(Pre) Cp+1=%d C'p+2=%d\n", bbcp!=0, bbcp1!=0) );
630 } /* End of "can lose a bit" */
632 /* Clean shifted C' */
633 mask = ~MPFR_LIMB_MASK (sh);
634 cp[0] &= mask;
636 /* Substract the mantissa c from b in a */
637 ap = MPFR_MANT(a);
638 mpn_sub_n (ap, bp, cp, n);
639 DEBUG( mpfr_print_mant_binary("Sub= ", ap, p) );
641 /* Normalize: we lose at max one bit*/
642 if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
644 /* High bit is not set and we have to fix it! */
645 /* Ap >= 010000xxx001 */
646 mpn_lshift(ap, ap, n, 1);
647 /* Ap >= 100000xxx010 */
648 if (MPFR_UNLIKELY(bcp!=0)) /* Check if Cp = -1 */
649 /* Since Cp == -1, we have to substract one more */
651 mpn_sub_1(ap, ap, n, MPFR_LIMB_ONE<<sh);
652 MPFR_ASSERTD(MPFR_LIMB_MSB(ap[n-1]) != 0);
654 /* Ap >= 10000xxx001 */
655 /* Final exponent -1 since we have shifted the mantissa */
656 bx--;
657 /* Update bcp and bcp1 */
658 MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
659 MPFR_ASSERTN(bbcp1 != (mp_limb_t) -1);
660 bcp = bbcp;
661 bcp1 = bbcp1;
662 /* We dont't have anymore a valid Cp+1!
663 But since Ap >= 100000xxx001, the final sub can't unnormalize!*/
665 MPFR_ASSERTD( !(ap[0] & ~mask) );
667 /* Rounding */
668 if (MPFR_LIKELY(rnd_mode == GMP_RNDN))
670 if (MPFR_LIKELY(bcp==0))
671 goto truncate;
672 else if ((bcp1) || ((ap[0] & (MPFR_LIMB_ONE<<sh)) != 0))
673 goto sub_one_ulp;
674 else
675 goto truncate;
678 /* Update rounding mode */
679 MPFR_UPDATE_RND_MODE(rnd_mode, MPFR_IS_NEG(a));
680 if (rnd_mode == GMP_RNDZ && (MPFR_LIKELY(bcp || bcp1)))
681 goto sub_one_ulp;
682 goto truncate;
684 MPFR_RET_NEVER_GO_HERE ();
686 /* Sub one ulp to the result */
687 sub_one_ulp:
688 mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
689 /* Result should be smaller than exact value: inexact=-1 */
690 inexact = -1;
691 /* Check normalisation */
692 if (MPFR_UNLIKELY(MPFR_LIMB_MSB(ap[n-1]) == 0))
694 /* ap was a power of 2, and we lose a bit */
695 /* Now it is 0111111111111111111[00000 */
696 mpn_lshift(ap, ap, n, 1);
697 bx--;
698 /* And the lost bit x depends on Cp+1, and Cp */
699 /* Compute Cp+1 if it isn't already compute (ie d==1) */
700 /* FIXME: Is this case possible? */
701 if (MPFR_UNLIKELY(d == 1))
702 bbcp = 0;
703 DEBUG( printf("(SubOneUlp)Cp=%d, Cp+1=%d C'p+1=%d\n", bcp!=0,bbcp!=0,bcp1!=0));
704 /* Compute the last bit (Since we have shifted the mantissa)
705 we need one more bit!*/
706 MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
707 if ( (rnd_mode == GMP_RNDZ && bcp==0)
708 || (rnd_mode==GMP_RNDN && bbcp==0)
709 || (bcp && bcp1==0) ) /*Exact result*/
711 ap[0] |= MPFR_LIMB_ONE<<sh;
712 if (rnd_mode == GMP_RNDN)
713 inexact = 1;
714 DEBUG( printf("(SubOneUlp) Last bit set\n") );
716 /* Result could be exact if C'p+1 = 0 and rnd == Zero
717 since we have had one more bit to the result */
718 /* Fixme: rnd_mode == GMP_RNDZ needed ? */
719 if (bcp1==0 && rnd_mode==GMP_RNDZ)
721 DEBUG( printf("(SubOneUlp) Exact result\n") );
722 inexact = 0;
726 goto end_of_sub;
728 truncate:
729 /* Check if the result is an exact power of 2: 100000000000
730 in which cases, we could have to do sub_one_ulp due to some nasty reasons:
731 If Result is a Power of 2:
732 + If rnd = AWAY,
733 | If Cp=-1 and C'p+1 = 0, SubOneUlp and the result is EXACT.
734 If Cp=-1 and C'p+1 =-1, SubOneUlp and the result is above.
735 Otherwise truncate
736 + If rnd = NEAREST,
737 If Cp= 0 and Cp+1 =-1 and C'p+2=-1, SubOneUlp and the result is above
738 If cp=-1 and C'p+1 = 0, SubOneUlp and the result is exact.
739 Otherwise truncate.
740 X bit should always be set if SubOneUlp*/
741 if (MPFR_UNLIKELY(ap[n-1] == MPFR_LIMB_HIGHBIT))
743 mp_size_t k = n-1;
744 do {
745 k--;
746 } while (k>=0 && ap[k]==0);
747 if (MPFR_UNLIKELY(k<0))
749 /* It is a power of 2! */
750 /* Compute Cp+1 if it isn't already compute (ie d==1) */
751 /* FIXME: Is this case possible? */
752 if (d == 1)
753 bbcp=0;
754 DEBUG( printf("(Truncate) Cp=%d, Cp+1=%d C'p+1=%d C'p+2=%d\n", \
755 bcp!=0, bbcp!=0, bcp1!=0, bbcp1!=0) );
756 MPFR_ASSERTN(bbcp != (mp_limb_t) -1);
757 MPFR_ASSERTN((rnd_mode != GMP_RNDN) || (bcp != 0) || (bbcp == 0) || (bbcp1 != (mp_limb_t) -1));
758 if (((rnd_mode != GMP_RNDZ) && bcp)
760 ((rnd_mode == GMP_RNDN) && (bcp == 0) && (bbcp) && (bbcp1)))
762 DEBUG( printf("(Truncate) Do sub\n") );
763 mpn_sub_1 (ap, ap, n, MPFR_LIMB_ONE << sh);
764 mpn_lshift(ap, ap, n, 1);
765 ap[0] |= MPFR_LIMB_ONE<<sh;
766 bx--;
767 /* FIXME: Explain why it works (or why not)... */
768 inexact = (bcp1 == 0) ? 0 : (rnd_mode==GMP_RNDN) ? -1 : 1;
769 goto end_of_sub;
774 /* Calcul of Inexact flag.*/
775 inexact = MPFR_LIKELY(bcp || bcp1) ? 1 : 0;
777 end_of_sub:
778 /* Update Expo */
779 /* FIXME: Is this test really useful?
780 If d==0 : Exact case. This is never called.
781 if 1 < d < p : bx=MPFR_EXP(b) or MPFR_EXP(b)-1 > MPFR_EXP(c) > emin
782 if d == 1 : bx=MPFR_EXP(b). If we could lose any bits, the exact
783 normalisation is called.
784 if d >= p : bx=MPFR_EXP(b) >= MPFR_EXP(c) + p > emin
785 After SubOneUlp, we could have one bit less.
786 if 1 < d < p : bx >= MPFR_EXP(b)-2 >= MPFR_EXP(c) > emin
787 if d == 1 : bx >= MPFR_EXP(b)-1 = MPFR_EXP(c) > emin.
788 if d >= p : bx >= MPFR_EXP(b)-1 > emin since p>=2.
790 MPFR_ASSERTD( bx >= __gmpfr_emin);
792 if (MPFR_UNLIKELY(bx < __gmpfr_emin))
794 DEBUG( printf("(Final Underflow)\n") );
795 if (rnd_mode == GMP_RNDN &&
796 (bx < __gmpfr_emin - 1 ||
797 (inexact >= 0 && mpfr_powerof2_raw (a))))
798 rnd_mode = GMP_RNDZ;
799 MPFR_TMP_FREE(marker);
800 return mpfr_underflow (a, rnd_mode, MPFR_SIGN(a));
803 MPFR_SET_EXP (a, bx);
805 MPFR_TMP_FREE(marker);
806 MPFR_RET (inexact * MPFR_INT_SIGN (a));