1 /* mpfr_div -- divide two floating-point numbers
3 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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. */
24 [1] Short Division of Long Integers, David Harvey and Paul Zimmermann,
25 Proceedings of the 20th Symposium on Computer Arithmetic (ARITH-20),
26 July 25-27, 2011, pages 7-14.
29 #define MPFR_NEED_LONGLONG_H
30 #include "mpfr-impl.h"
33 #define mpfr_mpn_print(ap,n) mpfr_mpn_print3 (ap,n,MPFR_LIMB_ZERO)
35 mpfr_mpn_print3 (mpfr_limb_ptr ap
, mp_size_t n
, mp_limb_t cy
)
38 for (i
= 0; i
< n
; i
++)
39 printf ("+%lu*2^%lu", (unsigned long) ap
[i
], (unsigned long)
42 printf ("+2^%lu", (unsigned long) (GMP_NUMB_BITS
* n
));
47 /* check if {ap, an} is zero */
49 mpfr_mpn_cmpzero (mpfr_limb_ptr ap
, mp_size_t an
)
52 if (MPFR_LIKELY(ap
[--an
] != MPFR_LIMB_ZERO
))
57 /* compare {ap, an} and {bp, bn} >> extra,
58 aligned by the more significant limbs.
59 Takes into account bp[0] for extra=1.
62 mpfr_mpn_cmp_aux (mpfr_limb_ptr ap
, mp_size_t an
,
63 mpfr_limb_ptr bp
, mp_size_t bn
, int extra
)
72 while (cmp
== 0 && bn
> 0)
75 bb
= (extra
) ? ((bp
[bn
+1] << (GMP_NUMB_BITS
- 1)) | (bp
[bn
] >> 1))
77 cmp
= (ap
[k
+ bn
] > bb
) ? 1 : ((ap
[k
+ bn
] < bb
) ? -1 : 0);
79 bb
= (extra
) ? bp
[0] << (GMP_NUMB_BITS
- 1) : MPFR_LIMB_ZERO
;
80 while (cmp
== 0 && k
> 0)
83 cmp
= (ap
[k
] > bb
) ? 1 : ((ap
[k
] < bb
) ? -1 : 0);
84 bb
= MPFR_LIMB_ZERO
; /* ensure we consider only once bp[0] & 1 */
86 if (cmp
== 0 && bb
!= MPFR_LIMB_ZERO
)
92 while (cmp
== 0 && an
> 0)
95 bb
= (extra
) ? ((bp
[k
+an
+1] << (GMP_NUMB_BITS
- 1)) | (bp
[k
+an
] >> 1))
102 while (cmp
== 0 && k
> 0)
105 bb
= (extra
) ? ((bp
[k
+1] << (GMP_NUMB_BITS
- 1)) | (bp
[k
] >> 1))
107 cmp
= (bb
!= MPFR_LIMB_ZERO
) ? -1 : 0;
109 if (cmp
== 0 && extra
&& (bp
[0] & MPFR_LIMB_ONE
))
115 /* {ap, n} <- {ap, n} - {bp, n} >> extra - cy, with cy = 0 or 1.
119 mpfr_mpn_sub_aux (mpfr_limb_ptr ap
, mpfr_limb_ptr bp
, mp_size_t n
,
120 mp_limb_t cy
, int extra
)
124 MPFR_ASSERTD (cy
<= 1);
127 bb
= (extra
) ? ((bp
[1] << (GMP_NUMB_BITS
-1)) | (bp
[0] >> 1)) : bp
[0];
128 rp
= ap
[0] - bb
- cy
;
129 cy
= (ap
[0] < bb
) || (cy
&& ~rp
== MPFR_LIMB_ZERO
) ?
130 MPFR_LIMB_ONE
: MPFR_LIMB_ZERO
;
135 MPFR_ASSERTD (cy
<= 1);
140 mpfr_div (mpfr_ptr q
, mpfr_srcptr u
, mpfr_srcptr v
, mpfr_rnd_t rnd_mode
)
142 mp_size_t q0size
= MPFR_LIMB_SIZE(q
); /* number of limbs of destination */
143 mp_size_t usize
= MPFR_LIMB_SIZE(u
);
144 mp_size_t vsize
= MPFR_LIMB_SIZE(v
);
145 mp_size_t qsize
; /* number of limbs wanted for the computed quotient */
148 mpfr_limb_ptr q0p
= MPFR_MANT(q
), qp
;
149 mpfr_limb_ptr up
= MPFR_MANT(u
);
150 mpfr_limb_ptr vp
= MPFR_MANT(v
);
154 mp_limb_t sticky_u
= MPFR_LIMB_ZERO
;
156 mp_limb_t sticky_v
= MPFR_LIMB_ZERO
;
159 mp_limb_t round_bit
= MPFR_LIMB_ZERO
;
166 MPFR_TMP_DECL(marker
);
169 ("u[%Pu]=%.*Rg v[%Pu]=%.*Rg rnd=%d",
170 mpfr_get_prec(u
), mpfr_log_prec
, u
,
171 mpfr_get_prec (v
),mpfr_log_prec
, v
, rnd_mode
),
172 ("q[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(q
), mpfr_log_prec
, q
, inex
));
174 /**************************************************************************
176 * This part of the code deals with special cases *
178 **************************************************************************/
180 if (MPFR_UNLIKELY(MPFR_ARE_SINGULAR(u
,v
)))
182 if (MPFR_IS_NAN(u
) || MPFR_IS_NAN(v
))
187 sign_quotient
= MPFR_MULT_SIGN( MPFR_SIGN(u
) , MPFR_SIGN(v
) );
188 MPFR_SET_SIGN(q
, sign_quotient
);
202 else if (MPFR_IS_INF(v
))
207 else if (MPFR_IS_ZERO (v
))
209 if (MPFR_IS_ZERO (u
))
216 MPFR_ASSERTD (! MPFR_IS_INF (u
));
224 MPFR_ASSERTD (MPFR_IS_ZERO (u
));
230 /**************************************************************************
232 * End of the part concerning special values. *
234 **************************************************************************/
236 MPFR_TMP_MARK(marker
);
239 sign_quotient
= MPFR_MULT_SIGN( MPFR_SIGN(u
) , MPFR_SIGN(v
) );
240 MPFR_SET_SIGN(q
, sign_quotient
);
242 /* determine if an extra bit comes from the division, i.e. if the
243 significand of u (as a fraction in [1/2, 1[) is larger than that
245 if (MPFR_LIKELY(up
[usize
- 1] != vp
[vsize
- 1]))
246 extra_bit
= (up
[usize
- 1] > vp
[vsize
- 1]) ? 1 : 0;
247 else /* most significant limbs are equal, must look at further limbs */
253 while (k
!= 0 && l
!= 0 && up
[--k
] == vp
[--l
]);
254 /* now k=0 or l=0 or up[k] != vp[l] */
257 else if (up
[k
] < vp
[l
])
259 /* now up[k] = vp[l], thus either k=0 or l=0 */
260 else if (l
== 0) /* no more divisor limb */
262 else /* k=0: no more dividend limb */
263 extra_bit
= mpfr_mpn_cmpzero (vp
, l
) == 0;
266 printf ("extra_bit=%d\n", extra_bit
);
270 qexp
= MPFR_GET_EXP (u
) - MPFR_GET_EXP (v
) + extra_bit
;
272 /* sh is the number of zero bits in the low limb of the quotient */
273 MPFR_UNSIGNED_MINUS_MODULO(sh
, MPFR_PREC(q
));
275 like_rndz
= rnd_mode
== MPFR_RNDZ
||
276 rnd_mode
== (sign_quotient
< 0 ? MPFR_RNDU
: MPFR_RNDD
);
278 /**************************************************************************
280 * We first try Mulders' short division (for large operands) *
282 **************************************************************************/
284 if (MPFR_UNLIKELY(q0size
>= MPFR_DIV_THRESHOLD
&&
285 vsize
>= MPFR_DIV_THRESHOLD
))
287 mp_size_t n
= q0size
+ 1; /* we will perform a short (2n)/n division */
288 mpfr_limb_ptr ap
, bp
, qp
;
291 /* since Mulders' short division clobbers the dividend, we have to
293 ap
= MPFR_TMP_LIMBS_ALLOC (n
+ n
);
294 if (usize
>= n
+ n
) /* truncate the dividend */
295 MPN_COPY(ap
, up
+ usize
- (n
+ n
), n
+ n
);
296 else /* zero-pad the dividend */
298 MPN_COPY(ap
+ (n
+ n
) - usize
, up
, usize
);
299 MPN_ZERO(ap
, (n
+ n
) - usize
);
302 if (vsize
>= n
) /* truncate the divisor */
304 else /* zero-pad the divisor */
306 bp
= MPFR_TMP_LIMBS_ALLOC (n
);
307 MPN_COPY(bp
+ n
- vsize
, vp
, vsize
);
308 MPN_ZERO(bp
, n
- vsize
);
311 qp
= MPFR_TMP_LIMBS_ALLOC (n
);
312 qh
= mpfr_divhigh_n (qp
, ap
, bp
, n
);
313 /* in all cases, the error is at most (2n+2) ulps on qh*B^n+{qp,n},
316 p
= n
* GMP_NUMB_BITS
- MPFR_INT_CEIL_LOG2 (2 * n
+ 2);
317 /* if qh is 1, then we need only PREC(q)-1 bits of {qp,n},
318 if rnd=RNDN, we need to be able to round with a directed rounding
320 if (MPFR_LIKELY (mpfr_round_p (qp
, n
, p
,
321 MPFR_PREC(q
) + (rnd_mode
== MPFR_RNDN
) - qh
)))
323 /* we can round correctly whatever the rounding mode */
325 MPN_COPY (q0p
, qp
+ 1, q0size
);
328 mpn_rshift (q0p
, qp
+ 1, q0size
, 1);
329 q0p
[q0size
- 1] ^= MPFR_LIMB_HIGHBIT
;
331 q0p
[0] &= ~MPFR_LIMB_MASK(sh
); /* put to zero low sh bits */
333 if (rnd_mode
== MPFR_RNDN
) /* round to nearest */
335 /* we know we can round, thus we are never in the even rule case:
336 if the round bit is 0, we truncate
337 if the round bit is 1, we add 1 */
341 round_bit
= (qp
[1] >> (sh
- 1)) & 1;
343 round_bit
= qp
[0] >> (GMP_NUMB_BITS
- 1);
346 round_bit
= (qp
[1] >> sh
) & 1;
352 else /* round_bit = 1 */
355 else if (like_rndz
== 0) /* round away */
357 /* else round to zero: nothing to do */
366 /**************************************************************************
368 * Mulders' short division failed: we revert to integer division *
370 **************************************************************************/
372 if (MPFR_UNLIKELY(rnd_mode
== MPFR_RNDN
&& sh
== 0))
373 { /* we compute the quotient with one more limb, in order to get
374 the round bit in the quotient, and the remainder only contains
377 /* need to allocate memory for the quotient */
378 qp
= MPFR_TMP_LIMBS_ALLOC (qsize
);
383 qp
= q0p
; /* directly put the quotient in the destination */
385 qqsize
= qsize
+ qsize
;
387 /* prepare the dividend */
388 ap
= MPFR_TMP_LIMBS_ALLOC (qqsize
);
389 if (MPFR_LIKELY(qqsize
> usize
)) /* use the full dividend */
391 k
= qqsize
- usize
; /* k > 0 */
394 ap
[k
- 1] = mpn_rshift (ap
+ k
, up
, usize
, 1);
396 MPN_COPY(ap
+ k
, up
, usize
);
398 else /* truncate the dividend */
402 sticky_u
= mpn_rshift (ap
, up
+ k
, qqsize
, 1);
404 MPN_COPY(ap
, up
+ k
, qqsize
);
405 sticky_u
= sticky_u
|| mpfr_mpn_cmpzero (up
, k
);
409 /* now sticky_u is non-zero iff the truncated part of u is non-zero */
411 /* prepare the divisor */
412 if (MPFR_LIKELY(vsize
>= qsize
))
416 bp
= vp
+ k
; /* avoid copying the divisor */
417 else /* need to copy, since mpn_divrem doesn't allow overlap
418 between quotient and divisor, necessarily k = 0
419 since quotient and divisor are the same mpfr variable */
421 bp
= MPFR_TMP_LIMBS_ALLOC (qsize
);
422 MPN_COPY(bp
, vp
, vsize
);
424 sticky_v
= sticky_v
|| mpfr_mpn_cmpzero (vp
, k
);
427 else /* vsize < qsize: small divisor case */
433 /**************************************************************************
435 * Here we perform the real division of {ap+k,qqsize-k} by {bp,qsize-k} *
437 **************************************************************************/
439 /* if Mulders' short division failed, we revert to division with remainder */
440 qh
= mpn_divrem (qp
, 0, ap
+ k
, qqsize
- k
, bp
, qsize
- k
);
441 /* warning: qh may be 1 if u1 == v1, but u < v */
443 printf ("q="); mpfr_mpn_print (qp
, qsize
);
444 printf ("r="); mpfr_mpn_print (ap
, qsize
);
448 sticky_u
= sticky_u
|| mpfr_mpn_cmpzero (ap
, k
);
450 sticky
= sticky_u
| sticky_v
;
452 /* now sticky is non-zero iff one of the following holds:
453 (a) the truncated part of u is non-zero
454 (b) the truncated part of v is non-zero
455 (c) the remainder from division is non-zero */
457 if (MPFR_LIKELY(qsize
== q0size
))
459 sticky3
= qp
[0] & MPFR_LIMB_MASK(sh
); /* does nothing when sh=0 */
462 else /* qsize = q0size + 1: only happens when rnd_mode=MPFR_RNDN and sh=0 */
464 MPN_COPY (q0p
, qp
+ 1, q0size
);
469 /* sticky3 contains the truncated bits from the quotient,
470 including the round bit, and 1 <= sh2 <= GMP_NUMB_BITS
471 is the number of bits in sticky3 */
472 inex
= (sticky
!= MPFR_LIMB_ZERO
) || (sticky3
!= MPFR_LIMB_ZERO
);
474 printf ("sticky=%lu sticky3=%lu inex=%d\n",
475 (unsigned long) sticky
, (unsigned long) sticky3
, inex
);
478 /* to round, we distinguish two cases:
479 (a) vsize <= qsize: we used the full divisor
480 (b) vsize > qsize: the divisor was truncated
484 printf ("vsize=%lu qsize=%lu\n",
485 (unsigned long) vsize
, (unsigned long) qsize
);
487 if (MPFR_LIKELY(vsize
<= qsize
)) /* use the full divisor */
489 if (MPFR_LIKELY(rnd_mode
== MPFR_RNDN
))
491 round_bit
= sticky3
& (MPFR_LIMB_ONE
<< (sh2
- 1));
492 sticky
= (sticky3
^ round_bit
) | sticky_u
;
494 else if (like_rndz
|| inex
== 0)
495 sticky
= (inex
== 0) ? MPFR_LIMB_ZERO
: MPFR_LIMB_ONE
;
496 else /* round away from zero */
497 sticky
= MPFR_LIMB_ONE
;
500 else /* vsize > qsize: need to truncate the divisor */
506 /* We know the estimated quotient is an upper bound of the exact
507 quotient (with rounding toward zero), with a difference of at
509 Thus we can round except when sticky3 is 000...000 or 000...001
510 for directed rounding, and 100...000 or 100...001 for rounding
511 to nearest. (For rounding to nearest, we cannot determine the
512 inexact flag for 000...000 or 000...001.)
514 mp_limb_t sticky3orig
= sticky3
;
515 if (rnd_mode
== MPFR_RNDN
)
517 round_bit
= sticky3
& (MPFR_LIMB_ONE
<< (sh2
- 1));
518 sticky3
= sticky3
^ round_bit
;
520 printf ("rb=%lu sb=%lu\n",
521 (unsigned long) round_bit
, (unsigned long) sticky3
);
524 if (sticky3
!= MPFR_LIMB_ZERO
&& sticky3
!= MPFR_LIMB_ONE
)
529 else /* hard case: we have to compare q1 * v0 and r + low(u),
530 where q1 * v0 has qsize + (vsize-qsize) = vsize limbs, and
531 r + low(u) has qsize + (usize-2*qsize) = usize-qsize limbs */
538 sp
= MPFR_TMP_LIMBS_ALLOC (vsize
);
540 /* sp <- {qp, qsize} * {vp, vsize-qsize} */
541 qp
[0] ^= sticky3orig
; /* restore original quotient */
543 mpn_mul (sp
, qp
, qsize
, vp
, k
);
545 mpn_mul (sp
, vp
, k
, qp
, qsize
);
547 qh2
= mpn_add_n (sp
+ qsize
, sp
+ qsize
, vp
, k
);
550 qp
[0] ^= sticky3orig
; /* restore truncated quotient */
552 /* compare qh2 + {sp, k + qsize} to {ap, qsize} + low(u) */
553 cmp_s_r
= (qh2
!= 0) ? 1 : mpn_cmp (sp
+ k
, ap
, qsize
);
554 if (cmp_s_r
== 0) /* compare {sp, k} and low(u) */
556 cmp_s_r
= (usize
>= qqsize
) ?
557 mpfr_mpn_cmp_aux (sp
, k
, up
, usize
- qqsize
, extra_bit
) :
558 mpfr_mpn_cmpzero (sp
, k
);
561 printf ("cmp(q*v0,r+u0)=%d\n", cmp_s_r
);
563 /* now cmp_s_r > 0 if {sp, vsize} > {ap, qsize} + low(u)
564 cmp_s_r = 0 if {sp, vsize} = {ap, qsize} + low(u)
565 cmp_s_r < 0 if {sp, vsize} < {ap, qsize} + low(u) */
566 if (cmp_s_r
<= 0) /* quotient is in [q1, q1+1) */
568 sticky
= (cmp_s_r
== 0) ? sticky3
: MPFR_LIMB_ONE
;
571 else /* cmp_s_r > 0, quotient is < q1: to determine if it is
572 in [q1-2,q1-1] or in [q1-1,q1], we need to subtract
573 the low part u0 of the dividend u0 from q*v0 */
575 mp_limb_t cy
= MPFR_LIMB_ZERO
;
577 /* subtract low(u)>>extra_bit if non-zero */
578 if (qh2
!= 0) /* whatever the value of {up, m + k}, it
579 will be smaller than qh2 + {sp, k} */
583 if (low_u
!= MPFR_LIMB_ZERO
)
586 l
= usize
- qqsize
; /* number of low limbs in u */
587 m
= (l
> k
) ? l
- k
: 0;
589 (up
[m
] & MPFR_LIMB_ONE
) : MPFR_LIMB_ZERO
;
590 if (l
>= k
) /* u0 has more limbs than s:
591 first look if {up, m} is not zero,
592 and compare {sp, k} and {up + m, k} */
594 cy
= cy
|| mpfr_mpn_cmpzero (up
, m
);
596 cy
= mpfr_mpn_sub_aux (sp
, up
+ m
, k
,
599 else /* l < k: s has more limbs than u0 */
601 low_u
= MPFR_LIMB_ZERO
;
602 if (cy
!= MPFR_LIMB_ZERO
)
603 cy
= mpn_sub_1 (sp
+ k
- l
- 1, sp
+ k
- l
- 1,
604 1, MPFR_LIMB_HIGHBIT
);
605 cy
= mpfr_mpn_sub_aux (sp
+ k
- l
, up
, l
,
609 MPFR_ASSERTD (cy
<= 1);
610 cy
= mpn_sub_1 (sp
+ k
, sp
+ k
, qsize
, cy
);
612 cy
+= mpn_sub_n (sp
+ k
, sp
+ k
, ap
, qsize
);
613 MPFR_ASSERTD (cy
<= 1);
614 /* now compare {sp, ssize} to v */
615 cmp_s_r
= mpn_cmp (sp
, vp
, vsize
);
616 if (cmp_s_r
== 0 && low_u
!= MPFR_LIMB_ZERO
)
617 cmp_s_r
= 1; /* since in fact we subtracted
621 printf ("cmp(q*v0-(r+u0),v)=%d\n", cmp_s_r
);
623 if (cmp_s_r
<= 0) /* q1-1 <= u/v < q1 */
625 if (sticky3
== MPFR_LIMB_ONE
)
626 { /* q1-1 is either representable (directed rounding),
627 or the middle of two numbers (nearest) */
628 sticky
= (cmp_s_r
) ? MPFR_LIMB_ONE
: MPFR_LIMB_ZERO
;
631 /* now necessarily sticky3=0 */
632 else if (round_bit
== MPFR_LIMB_ZERO
)
633 { /* round_bit=0, sticky3=0: q1-1 is exact only
635 inex
= (cmp_s_r
|| sh
) ? -1 : 0;
636 if (rnd_mode
== MPFR_RNDN
||
637 (! like_rndz
&& inex
!= 0))
640 goto truncate_check_qh
;
642 else /* round down */
645 else /* sticky3=0, round_bit=1 ==> rounding to nearest */
651 else /* q1-2 < u/v < q1-1 */
653 /* if rnd=MPFR_RNDN, the result is q1 when
654 q1-2 >= q1-2^(sh-1), i.e. sh >= 2,
655 otherwise (sh=1) it is q1-2 */
656 if (rnd_mode
== MPFR_RNDN
) /* sh > 0 */
658 /* Case sh=1: sb=0 always, and q1-rb is exactly
659 representable, like q1-rb-2.
661 0 subtract two ulps, inex=-1
664 Case sh>1: one ulp is 2^(sh-1) >= 2
668 1 x truncate, inex=-1
672 if (round_bit
== MPFR_LIMB_ZERO
)
681 goto truncate_check_qh
;
686 inex
= (round_bit
== MPFR_LIMB_ZERO
) ? 1 : -1;
687 goto truncate_check_qh
;
692 /* the result is down(q1-2), i.e. subtract one
693 ulp if sh > 0, and two ulps if sh=0 */
700 /* if round away from zero, the result is up(q1-1),
701 which is q1 unless sh = 0, where it is q1-1 */
706 goto truncate_check_qh
;
716 case_1
: /* quotient is in [q1, q1+1),
717 round_bit is the round_bit (0 for directed rounding),
718 sticky the sticky bit */
719 if (like_rndz
|| (round_bit
== MPFR_LIMB_ZERO
&& sticky
== MPFR_LIMB_ZERO
))
721 inex
= round_bit
== MPFR_LIMB_ZERO
&& sticky
== MPFR_LIMB_ZERO
? 0 : -1;
724 else if (rnd_mode
== MPFR_RNDN
) /* sticky <> 0 or round <> 0 */
726 if (round_bit
== MPFR_LIMB_ZERO
) /* necessarily sticky <> 0 */
732 else if (sticky
!= MPFR_LIMB_ZERO
)
733 goto add_one_ulp
; /* inex=1 */
734 else /* round_bit=1, sticky=0 */
737 else /* round away from zero, sticky <> 0 */
738 goto add_one_ulp
; /* with inex=1 */
741 /* we cannot subtract MPFR_LIMB_MPFR_LIMB_ONE << (sh+1) since this is
742 undefined for sh = GMP_NUMB_BITS */
743 qh
-= mpn_sub_1 (q0p
, q0p
, q0size
, MPFR_LIMB_ONE
<< sh
);
747 qh
-= mpn_sub_1 (q0p
, q0p
, q0size
, MPFR_LIMB_ONE
<< sh
);
748 /* go through truncate_check_qh */
754 q0p
[q0size
- 1] = MPFR_LIMB_HIGHBIT
;
758 even_rule
: /* has to set inex */
759 inex
= (q0p
[0] & (MPFR_LIMB_ONE
<< sh
)) ? 1 : -1;
762 /* else go through add_one_ulp */
765 inex
= 1; /* always here */
766 if (mpn_add_1 (q0p
, q0p
, q0size
, MPFR_LIMB_ONE
<< sh
))
769 q0p
[q0size
- 1] = MPFR_LIMB_HIGHBIT
;
772 truncate
: /* inex already set */
774 MPFR_TMP_FREE(marker
);
776 /* check for underflow/overflow */
777 if (MPFR_UNLIKELY(qexp
> __gmpfr_emax
))
778 return mpfr_overflow (q
, rnd_mode
, sign_quotient
);
779 else if (MPFR_UNLIKELY(qexp
< __gmpfr_emin
))
781 if (rnd_mode
== MPFR_RNDN
&& ((qexp
< __gmpfr_emin
- 1) ||
782 (inex
>= 0 && mpfr_powerof2_raw (q
))))
783 rnd_mode
= MPFR_RNDZ
;
784 return mpfr_underflow (q
, rnd_mode
, sign_quotient
);
786 MPFR_SET_EXP(q
, qexp
);
788 inex
*= sign_quotient
;