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 */
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",
67 mpfr_clears (tmpa
, tmpb
, tmpc
, (mpfr_ptr
) 0);
70 # define mpfr_sub1sp mpfr_sub1sp2
74 /* Debugging support */
79 # define DEBUG(x) /**/
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.
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*/
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
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
120 * If carry, then it is 11111111111 + 1 = 10000000000000
121 * ap[n-1]=MPFR_HIGHT_BIT
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.
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
)
139 mp_prec_t p
, sh
, cnt
;
141 mp_limb_t
*ap
, *bp
, *cp
;
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 */
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
))
166 /* Check mantissa since exponent are equals */
169 while (k
>=0 && MPFR_UNLIKELY(bp
[k
] == cp
[k
]))
171 if (MPFR_UNLIKELY(k
< 0))
174 /* Return exact number 0 */
175 if (rnd_mode
== GMP_RNDD
)
182 else if (bp
[k
] > cp
[k
])
186 MPFR_ASSERTD(bp
[k
]<cp
[k
]);
190 else if (MPFR_UNLIKELY(bx
< cx
))
192 /* Swap b and c and set sign */
196 MPFR_SET_OPPOSITE_SIGN(a
,b
);
198 tx
= bx
; bx
= cx
; cx
= tx
;
204 MPFR_SET_SAME_SIGN(a
,b
);
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))
217 <-- c --> : exact sub */
219 mpn_sub_n (ap
, MPFR_MANT(b
), MPFR_MANT(c
), n
);
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
)));
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 );
248 MPFR_ASSERTD(limb
!= 0);
249 count_leading_zeros(cnt
, limb
);
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*/
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
);
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
))))
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
);
283 else /* if (d == 1) */
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 */
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 */
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! */
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
);
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 */
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) )
335 MPFR_UPDATE_RND_MODE(rnd_mode
, MPFR_IS_NEG(a
));
336 if (rnd_mode
== GMP_RNDZ
)
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 */
347 bp
= (mp_limb_t
*) MPFR_TMP_ALLOC (n
* BYTES_PER_MP_LIMB
);
348 mpn_lshift (bp
, MPFR_MANT(b
), n
, 1);
350 mpn_sub_n (ap
, bp
, cp
, n
);
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 */
364 carry
= cp
[k
]&MPFR_LIMB_ONE
;
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);
377 /* Result is a power of 2 */
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
);
387 /* carry = cp[k]/2+(cp[k-1]&1)<<(BITS_PER_MP_LIMB-1) = c'[k]*/
388 else if (bp
[k
] > carry
)
392 MPFR_ASSERTD(bp
[k
]<carry
);
398 else if (MPFR_UNLIKELY(d
>= p
))
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 = ? */
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
))
416 if (MPFR_UNLIKELY(cp
[n
-1] == MPFR_LIMB_HIGHBIT
))
421 } while (k
>=0 && cp
[k
]==0);
427 DEBUG( printf("(D=P) Cp=-1 Cp+1=%d C'p+1=%d \n", bbcp
!=0, bcp1
!=0) );
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)
444 MPFR_UPDATE_RND_MODE(rnd_mode
, MPFR_IS_NEG(a
));
445 if (rnd_mode
== GMP_RNDZ
)
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
))
466 if (MPFR_UNLIKELY(cp
[n
-1] == MPFR_LIMB_HIGHBIT
))
471 } while (k
>=0 && cp
[k
]==0);
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
);
481 if (MPFR_LIKELY(rnd_mode
== GMP_RNDN
))
483 MPFR_UPDATE_RND_MODE(rnd_mode
, MPFR_IS_NEG(a
));
484 if (rnd_mode
== GMP_RNDZ
)
486 else /* rnd_mode = AWAY */
492 mp_exp_unsigned_t dm
;
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 */
507 MPN_COPY(cp
, MPFR_MANT(c
)+m
, n
-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
);
518 /* dm > 0 and m > 0: shift and zero */
519 mpn_rshift(cp
, MPFR_MANT(c
)+m
, n
-m
, dm
);
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 */
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) ))
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*/
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
))
557 /*If sx==0, tp[kx] hasn't been checked*/
560 } while (kx
>=0 && tp
[kx
]==0);
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 */
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
))
581 /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
584 } while (kx
>=0 && tp
[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 */
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))
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 */
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
);
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
))))
621 /*kx += (sx==0);*/ /*If sx==0, tp[kx] hasn't been checked*/
624 } while (kx
>=0 && tp
[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
);
636 /* Substract the mantissa c from b in 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 */
657 /* Update bcp and bcp1 */
658 MPFR_ASSERTN(bbcp
!= (mp_limb_t
) -1);
659 MPFR_ASSERTN(bbcp1
!= (mp_limb_t
) -1);
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
) );
668 if (MPFR_LIKELY(rnd_mode
== GMP_RNDN
))
670 if (MPFR_LIKELY(bcp
==0))
672 else if ((bcp1
) || ((ap
[0] & (MPFR_LIMB_ONE
<<sh
)) != 0))
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
)))
684 MPFR_RET_NEVER_GO_HERE ();
686 /* Sub one ulp to the result */
688 mpn_sub_1 (ap
, ap
, n
, MPFR_LIMB_ONE
<< sh
);
689 /* Result should be smaller than exact value: 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);
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))
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
)
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") );
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:
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.
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.
740 X bit should always be set if SubOneUlp*/
741 if (MPFR_UNLIKELY(ap
[n
-1] == MPFR_LIMB_HIGHBIT
))
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? */
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
;
767 /* FIXME: Explain why it works (or why not)... */
768 inexact
= (bcp1
== 0) ? 0 : (rnd_mode
==GMP_RNDN
) ? -1 : 1;
774 /* Calcul of Inexact flag.*/
775 inexact
= MPFR_LIKELY(bcp
|| bcp1
) ? 1 : 0;
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))))
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
));