Home | History | Annotate | Line # | Download | only in src
      1      1.1  mrg /* mpfr_set_ld -- convert a machine long double to
      2      1.1  mrg                   a multiple precision floating-point number
      3      1.1  mrg 
      4  1.1.1.5  mrg Copyright 2002-2023 Free Software Foundation, Inc.
      5  1.1.1.2  mrg Contributed by the AriC and Caramba projects, INRIA.
      6      1.1  mrg 
      7      1.1  mrg This file is part of the GNU MPFR Library.
      8      1.1  mrg 
      9      1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
     10      1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     11      1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     12      1.1  mrg option) any later version.
     13      1.1  mrg 
     14      1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     15      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16      1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     17      1.1  mrg License for more details.
     18      1.1  mrg 
     19      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     20      1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     21  1.1.1.4  mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     22      1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     23      1.1  mrg 
     24  1.1.1.3  mrg #include <float.h> /* needed so that MPFR_LDBL_MANT_DIG is correctly defined */
     25      1.1  mrg 
     26      1.1  mrg #define MPFR_NEED_LONGLONG_H
     27      1.1  mrg #include "mpfr-impl.h"
     28      1.1  mrg 
     29  1.1.1.4  mrg /* To check for +inf, one can use the test x > LDBL_MAX, as LDBL_MAX is
     30  1.1.1.4  mrg    the maximum finite number representable in a long double, according
     31  1.1.1.3  mrg    to DR 467; see
     32  1.1.1.5  mrg      https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2092.htm
     33  1.1.1.3  mrg    If this fails on some platform, a test x - x != 0 might be used. */
     34  1.1.1.3  mrg 
     35  1.1.1.3  mrg #if defined(HAVE_LDOUBLE_IS_DOUBLE)
     36  1.1.1.3  mrg 
     37  1.1.1.3  mrg /* the "long double" format is the same as "double" */
     38  1.1.1.3  mrg int
     39  1.1.1.3  mrg mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
     40  1.1.1.3  mrg {
     41  1.1.1.3  mrg   return mpfr_set_d (r, (double) d, rnd_mode);
     42  1.1.1.3  mrg }
     43  1.1.1.3  mrg 
     44  1.1.1.3  mrg #elif defined(HAVE_LDOUBLE_IEEE_EXT_LITTLE)
     45  1.1.1.3  mrg 
     46  1.1.1.4  mrg #if GMP_NUMB_BITS >= 64
     47  1.1.1.4  mrg # define MPFR_LIMBS_PER_LONG_DOUBLE 1
     48  1.1.1.4  mrg #elif GMP_NUMB_BITS == 32
     49  1.1.1.4  mrg # define MPFR_LIMBS_PER_LONG_DOUBLE 2
     50  1.1.1.4  mrg #elif GMP_NUMB_BITS == 16
     51  1.1.1.4  mrg # define MPFR_LIMBS_PER_LONG_DOUBLE 4
     52  1.1.1.4  mrg #elif GMP_NUMB_BITS == 8
     53  1.1.1.4  mrg # define MPFR_LIMBS_PER_LONG_DOUBLE 8
     54  1.1.1.4  mrg #else
     55  1.1.1.4  mrg #error "GMP_NUMB_BITS is assumed to be 8, 16, 32 or >= 64"
     56  1.1.1.4  mrg #endif
     57  1.1.1.4  mrg /* The hypothetical GMP_NUMB_BITS == 16 is not supported. It will trigger
     58  1.1.1.4  mrg    an error below. */
     59  1.1.1.4  mrg 
     60  1.1.1.3  mrg /* IEEE Extended Little Endian Code */
     61  1.1.1.3  mrg int
     62  1.1.1.3  mrg mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
     63  1.1.1.3  mrg {
     64  1.1.1.4  mrg   int inexact, k, cnt;
     65  1.1.1.3  mrg   mpfr_t tmp;
     66  1.1.1.3  mrg   mp_limb_t tmpmant[MPFR_LIMBS_PER_LONG_DOUBLE];
     67  1.1.1.3  mrg   mpfr_long_double_t x;
     68  1.1.1.3  mrg   mpfr_exp_t exp;
     69  1.1.1.3  mrg   int signd;
     70  1.1.1.3  mrg   MPFR_SAVE_EXPO_DECL (expo);
     71  1.1.1.3  mrg 
     72  1.1.1.3  mrg   /* Check for NAN */
     73  1.1.1.3  mrg   if (MPFR_UNLIKELY (DOUBLE_ISNAN (d)))
     74  1.1.1.3  mrg     {
     75  1.1.1.5  mrg       /* we don't propagate the sign bit */
     76  1.1.1.3  mrg       MPFR_SET_NAN (r);
     77  1.1.1.3  mrg       MPFR_RET_NAN;
     78  1.1.1.3  mrg     }
     79  1.1.1.3  mrg   /* Check for INF */
     80  1.1.1.4  mrg   else if (MPFR_UNLIKELY (d > LDBL_MAX))
     81  1.1.1.3  mrg     {
     82  1.1.1.3  mrg       MPFR_SET_INF (r);
     83  1.1.1.3  mrg       MPFR_SET_POS (r);
     84  1.1.1.3  mrg       return 0;
     85  1.1.1.3  mrg     }
     86  1.1.1.4  mrg   else if (MPFR_UNLIKELY (d < -LDBL_MAX))
     87  1.1.1.3  mrg     {
     88  1.1.1.3  mrg       MPFR_SET_INF (r);
     89  1.1.1.3  mrg       MPFR_SET_NEG (r);
     90  1.1.1.3  mrg       return 0;
     91  1.1.1.3  mrg     }
     92  1.1.1.3  mrg   /* Check for ZERO */
     93  1.1.1.3  mrg   else if (MPFR_UNLIKELY (d == 0.0))
     94  1.1.1.3  mrg     {
     95  1.1.1.3  mrg       x.ld = d;
     96  1.1.1.3  mrg       MPFR_SET_ZERO (r);
     97  1.1.1.3  mrg       if (x.s.sign == 1)
     98  1.1.1.3  mrg         MPFR_SET_NEG(r);
     99  1.1.1.3  mrg       else
    100  1.1.1.3  mrg         MPFR_SET_POS(r);
    101  1.1.1.3  mrg       return 0;
    102  1.1.1.3  mrg     }
    103  1.1.1.3  mrg 
    104  1.1.1.3  mrg   /* now d is neither 0, nor NaN nor Inf */
    105  1.1.1.3  mrg   MPFR_SAVE_EXPO_MARK (expo);
    106  1.1.1.3  mrg 
    107  1.1.1.3  mrg   MPFR_MANT (tmp) = tmpmant;
    108  1.1.1.3  mrg   MPFR_PREC (tmp) = 64;
    109  1.1.1.3  mrg 
    110  1.1.1.3  mrg   /* Extract sign */
    111  1.1.1.3  mrg   x.ld = d;
    112  1.1.1.3  mrg   signd = MPFR_SIGN_POS;
    113  1.1.1.3  mrg   if (x.ld < 0.0)
    114  1.1.1.3  mrg     {
    115  1.1.1.3  mrg       signd = MPFR_SIGN_NEG;
    116  1.1.1.3  mrg       x.ld = -x.ld;
    117  1.1.1.3  mrg     }
    118  1.1.1.3  mrg 
    119  1.1.1.4  mrg   /* Extract and normalize the significand */
    120  1.1.1.4  mrg #if MPFR_LIMBS_PER_LONG_DOUBLE == 1
    121  1.1.1.3  mrg   tmpmant[0] = ((mp_limb_t) x.s.manh << 32) | ((mp_limb_t) x.s.manl);
    122  1.1.1.4  mrg   count_leading_zeros (cnt, tmpmant[0]);
    123  1.1.1.4  mrg   tmpmant[0] <<= cnt;
    124  1.1.1.4  mrg   k = 0; /* number of limbs shifted */
    125  1.1.1.4  mrg #else /* MPFR_LIMBS_PER_LONG_DOUBLE >= 2 */
    126  1.1.1.4  mrg #if MPFR_LIMBS_PER_LONG_DOUBLE == 2
    127  1.1.1.3  mrg   tmpmant[0] = (mp_limb_t) x.s.manl;
    128  1.1.1.3  mrg   tmpmant[1] = (mp_limb_t) x.s.manh;
    129  1.1.1.4  mrg #elif MPFR_LIMBS_PER_LONG_DOUBLE == 4
    130  1.1.1.4  mrg   tmpmant[0] = (mp_limb_t) x.s.manl;
    131  1.1.1.4  mrg   tmpmant[1] = (mp_limb_t) (x.s.manl >> 16);
    132  1.1.1.4  mrg   tmpmant[2] = (mp_limb_t) x.s.manh;
    133  1.1.1.4  mrg   tmpmant[3] = (mp_limb_t) (x.s.manh >> 16);
    134  1.1.1.4  mrg #elif MPFR_LIMBS_PER_LONG_DOUBLE == 8
    135  1.1.1.4  mrg   tmpmant[0] = (mp_limb_t) x.s.manl;
    136  1.1.1.4  mrg   tmpmant[1] = (mp_limb_t) (x.s.manl >> 8);
    137  1.1.1.4  mrg   tmpmant[2] = (mp_limb_t) (x.s.manl >> 16);
    138  1.1.1.4  mrg   tmpmant[3] = (mp_limb_t) (x.s.manl >> 24);
    139  1.1.1.4  mrg   tmpmant[4] = (mp_limb_t) x.s.manh;
    140  1.1.1.4  mrg   tmpmant[5] = (mp_limb_t) (x.s.manh >> 8);
    141  1.1.1.4  mrg   tmpmant[6] = (mp_limb_t) (x.s.manh >> 16);
    142  1.1.1.4  mrg   tmpmant[7] = (mp_limb_t) (x.s.manh >> 24);
    143  1.1.1.4  mrg #else
    144  1.1.1.4  mrg #error "MPFR_LIMBS_PER_LONG_DOUBLE should be 1, 2, 4 or 8"
    145  1.1.1.4  mrg #endif /* MPFR_LIMBS_PER_LONG_DOUBLE >= 2 */
    146  1.1.1.4  mrg   {
    147  1.1.1.4  mrg     int i = MPFR_LIMBS_PER_LONG_DOUBLE;
    148  1.1.1.4  mrg     MPN_NORMALIZE_NOT_ZERO (tmpmant, i);
    149  1.1.1.4  mrg     k = MPFR_LIMBS_PER_LONG_DOUBLE - i;
    150  1.1.1.4  mrg     count_leading_zeros (cnt, tmpmant[i - 1]);
    151  1.1.1.4  mrg     if (cnt != 0)
    152  1.1.1.4  mrg       mpn_lshift (tmpmant + k, tmpmant, i, cnt);
    153  1.1.1.4  mrg     else if (k != 0)
    154  1.1.1.4  mrg       /* since we copy {tmpmant, i} into {tmpmant + k, i}, we should work
    155  1.1.1.4  mrg          decreasingly, thus call mpn_copyd */
    156  1.1.1.4  mrg       mpn_copyd (tmpmant + k, tmpmant, i);
    157  1.1.1.4  mrg     if (k != 0)
    158  1.1.1.4  mrg       MPN_ZERO (tmpmant, k);
    159  1.1.1.4  mrg   }
    160  1.1.1.4  mrg #endif /* MPFR_LIMBS_PER_LONG_DOUBLE == 1 */
    161  1.1.1.3  mrg 
    162  1.1.1.3  mrg   /* Set exponent */
    163  1.1.1.3  mrg   exp = (mpfr_exp_t) ((x.s.exph << 8) + x.s.expl);  /* 15-bit unsigned int */
    164  1.1.1.3  mrg   if (MPFR_UNLIKELY (exp == 0))
    165  1.1.1.3  mrg     exp -= 0x3FFD;
    166  1.1.1.3  mrg   else
    167  1.1.1.3  mrg     exp -= 0x3FFE;
    168  1.1.1.3  mrg 
    169  1.1.1.3  mrg   MPFR_SET_EXP (tmp, exp - cnt - k * GMP_NUMB_BITS);
    170  1.1.1.3  mrg 
    171  1.1.1.3  mrg   /* tmp is exact */
    172  1.1.1.3  mrg   inexact = mpfr_set4 (r, tmp, rnd_mode, signd);
    173  1.1.1.3  mrg 
    174  1.1.1.3  mrg   MPFR_SAVE_EXPO_FREE (expo);
    175  1.1.1.3  mrg   return mpfr_check_range (r, inexact, rnd_mode);
    176  1.1.1.3  mrg }
    177  1.1.1.3  mrg 
    178  1.1.1.3  mrg #elif defined(HAVE_LDOUBLE_MAYBE_DOUBLE_DOUBLE)
    179  1.1.1.3  mrg 
    180  1.1.1.5  mrg /* double-double code, see
    181  1.1.1.5  mrg    https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/config/rs6000/ibm-ldouble-format;h=e8ada17f7696cd942e710d5b67d4149f5fcccf45;hb=HEAD */
    182  1.1.1.3  mrg int
    183  1.1.1.3  mrg mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
    184  1.1.1.3  mrg {
    185  1.1.1.3  mrg   mpfr_t t, u;
    186  1.1.1.4  mrg   int inexact;
    187  1.1.1.3  mrg   double h, l;
    188  1.1.1.3  mrg   MPFR_SAVE_EXPO_DECL (expo);
    189  1.1.1.3  mrg 
    190  1.1.1.5  mrg   /* Check for NAN. Since we can't use isnan(), we rely on the
    191  1.1.1.5  mrg      LONGDOUBLE_NAN_ACTION macro. The sign bit is not propagated. */
    192  1.1.1.5  mrg   LONGDOUBLE_NAN_ACTION (d, { MPFR_SET_NAN(r); MPFR_RET_NAN; });
    193  1.1.1.3  mrg 
    194  1.1.1.3  mrg   /* Check for INF */
    195  1.1.1.4  mrg   if (d > LDBL_MAX)
    196  1.1.1.3  mrg     {
    197  1.1.1.3  mrg       mpfr_set_inf (r, 1);
    198  1.1.1.3  mrg       return 0;
    199  1.1.1.3  mrg     }
    200  1.1.1.4  mrg   else if (d < -LDBL_MAX)
    201  1.1.1.3  mrg     {
    202  1.1.1.3  mrg       mpfr_set_inf (r, -1);
    203  1.1.1.3  mrg       return 0;
    204  1.1.1.3  mrg     }
    205  1.1.1.3  mrg   /* Check for ZERO */
    206  1.1.1.3  mrg   else if (d == 0.0)
    207  1.1.1.3  mrg     return mpfr_set_d (r, (double) d, rnd_mode);
    208  1.1.1.3  mrg 
    209  1.1.1.4  mrg   if (d >= LDBL_MAX || d <= -LDBL_MAX)
    210  1.1.1.4  mrg     h = (d >= LDBL_MAX) ? LDBL_MAX : -LDBL_MAX;
    211  1.1.1.3  mrg   else
    212  1.1.1.3  mrg     h = (double) d; /* should not overflow */
    213  1.1.1.3  mrg   l = (double) (d - (long double) h);
    214  1.1.1.3  mrg 
    215  1.1.1.3  mrg   MPFR_SAVE_EXPO_MARK (expo);
    216  1.1.1.3  mrg 
    217  1.1.1.3  mrg   mpfr_init2 (t, IEEE_DBL_MANT_DIG);
    218  1.1.1.3  mrg   mpfr_init2 (u, IEEE_DBL_MANT_DIG);
    219  1.1.1.3  mrg 
    220  1.1.1.3  mrg   inexact = mpfr_set_d (t, h, MPFR_RNDN);
    221  1.1.1.3  mrg   MPFR_ASSERTN(inexact == 0);
    222  1.1.1.3  mrg   inexact = mpfr_set_d (u, l, MPFR_RNDN);
    223  1.1.1.3  mrg   MPFR_ASSERTN(inexact == 0);
    224  1.1.1.3  mrg   inexact = mpfr_add (r, t, u, rnd_mode);
    225  1.1.1.3  mrg 
    226  1.1.1.3  mrg   mpfr_clear (t);
    227  1.1.1.3  mrg   mpfr_clear (u);
    228  1.1.1.3  mrg 
    229  1.1.1.3  mrg   MPFR_SAVE_EXPO_FREE (expo);
    230  1.1.1.3  mrg   inexact = mpfr_check_range (r, inexact, rnd_mode);
    231  1.1.1.3  mrg   return inexact;
    232  1.1.1.3  mrg }
    233  1.1.1.3  mrg 
    234  1.1.1.3  mrg #else
    235      1.1  mrg 
    236      1.1  mrg /* Generic code */
    237      1.1  mrg int
    238      1.1  mrg mpfr_set_ld (mpfr_ptr r, long double d, mpfr_rnd_t rnd_mode)
    239      1.1  mrg {
    240      1.1  mrg   mpfr_t t, u;
    241      1.1  mrg   int inexact, shift_exp;
    242      1.1  mrg   long double x;
    243      1.1  mrg   MPFR_SAVE_EXPO_DECL (expo);
    244      1.1  mrg 
    245  1.1.1.5  mrg   /* Check for NAN. Since we can't use isnan(), we rely on the
    246  1.1.1.5  mrg      LONGDOUBLE_NAN_ACTION macro. The sign bit is not propagated. */
    247  1.1.1.5  mrg   LONGDOUBLE_NAN_ACTION (d, { MPFR_SET_NAN(r); MPFR_RET_NAN; });
    248      1.1  mrg 
    249      1.1  mrg   /* Check for INF */
    250  1.1.1.4  mrg   if (d > LDBL_MAX)
    251      1.1  mrg     {
    252      1.1  mrg       mpfr_set_inf (r, 1);
    253      1.1  mrg       return 0;
    254      1.1  mrg     }
    255  1.1.1.4  mrg   else if (d < -LDBL_MAX)
    256      1.1  mrg     {
    257      1.1  mrg       mpfr_set_inf (r, -1);
    258      1.1  mrg       return 0;
    259      1.1  mrg     }
    260      1.1  mrg   /* Check for ZERO */
    261      1.1  mrg   else if (d == 0.0)
    262      1.1  mrg     return mpfr_set_d (r, (double) d, rnd_mode);
    263      1.1  mrg 
    264      1.1  mrg   mpfr_init2 (t, MPFR_LDBL_MANT_DIG);
    265      1.1  mrg   mpfr_init2 (u, IEEE_DBL_MANT_DIG);
    266      1.1  mrg 
    267      1.1  mrg   MPFR_SAVE_EXPO_MARK (expo);
    268      1.1  mrg 
    269      1.1  mrg  convert:
    270      1.1  mrg   x = d;
    271      1.1  mrg   MPFR_SET_ZERO (t);  /* The sign doesn't matter. */
    272      1.1  mrg   shift_exp = 0; /* invariant: remainder to deal with is d*2^shift_exp */
    273      1.1  mrg   while (x != (long double) 0.0)
    274      1.1  mrg     {
    275      1.1  mrg       /* Check overflow of double */
    276      1.1  mrg       if (x > (long double) DBL_MAX || (-x) > (long double) DBL_MAX)
    277      1.1  mrg         {
    278      1.1  mrg           long double div9, div10, div11, div12, div13;
    279      1.1  mrg 
    280      1.1  mrg #define TWO_64 18446744073709551616.0 /* 2^64 */
    281      1.1  mrg #define TWO_128 (TWO_64 * TWO_64)
    282      1.1  mrg #define TWO_256 (TWO_128 * TWO_128)
    283      1.1  mrg           div9 = (long double) (double) (TWO_256 * TWO_256); /* 2^(2^9) */
    284      1.1  mrg           div10 = div9 * div9;
    285      1.1  mrg           div11 = div10 * div10; /* 2^(2^11) */
    286      1.1  mrg           div12 = div11 * div11; /* 2^(2^12) */
    287      1.1  mrg           div13 = div12 * div12; /* 2^(2^13) */
    288      1.1  mrg           if (ABS (x) >= div13)
    289      1.1  mrg             {
    290      1.1  mrg               x /= div13; /* exact */
    291      1.1  mrg               shift_exp += 8192;
    292      1.1  mrg               mpfr_div_2si (t, t, 8192, MPFR_RNDZ);
    293      1.1  mrg             }
    294      1.1  mrg           if (ABS (x) >= div12)
    295      1.1  mrg             {
    296      1.1  mrg               x /= div12; /* exact */
    297      1.1  mrg               shift_exp += 4096;
    298      1.1  mrg               mpfr_div_2si (t, t, 4096, MPFR_RNDZ);
    299      1.1  mrg             }
    300      1.1  mrg           if (ABS (x) >= div11)
    301      1.1  mrg             {
    302      1.1  mrg               x /= div11; /* exact */
    303      1.1  mrg               shift_exp += 2048;
    304      1.1  mrg               mpfr_div_2si (t, t, 2048, MPFR_RNDZ);
    305      1.1  mrg             }
    306      1.1  mrg           if (ABS (x) >= div10)
    307      1.1  mrg             {
    308      1.1  mrg               x /= div10; /* exact */
    309      1.1  mrg               shift_exp += 1024;
    310      1.1  mrg               mpfr_div_2si (t, t, 1024, MPFR_RNDZ);
    311      1.1  mrg             }
    312      1.1  mrg           /* warning: we may have DBL_MAX=2^1024*(1-2^(-53)) < x < 2^1024,
    313      1.1  mrg              therefore we have one extra exponent reduction step */
    314      1.1  mrg           if (ABS (x) >= div9)
    315      1.1  mrg             {
    316      1.1  mrg               x /= div9; /* exact */
    317      1.1  mrg               shift_exp += 512;
    318      1.1  mrg               mpfr_div_2si (t, t, 512, MPFR_RNDZ);
    319      1.1  mrg             }
    320      1.1  mrg         } /* Check overflow of double */
    321      1.1  mrg       else /* no overflow on double */
    322      1.1  mrg         {
    323      1.1  mrg           long double div9, div10, div11;
    324      1.1  mrg 
    325      1.1  mrg           div9 = (long double) (double) 7.4583407312002067432909653e-155;
    326      1.1  mrg           /* div9 = 2^(-2^9) */
    327      1.1  mrg           div10 = div9  * div9;  /* 2^(-2^10) */
    328      1.1  mrg           div11 = div10 * div10; /* 2^(-2^11) if extended precision */
    329      1.1  mrg           /* since -DBL_MAX <= x <= DBL_MAX, the cast to double should not
    330      1.1  mrg              overflow here */
    331      1.1  mrg           if (ABS(x) < div10 &&
    332      1.1  mrg               div11 != (long double) 0.0 &&
    333      1.1  mrg               div11 / div10 == div10) /* possible underflow */
    334      1.1  mrg             {
    335      1.1  mrg               long double div12, div13;
    336      1.1  mrg               /* After the divisions, any bit of x must be >= div10,
    337      1.1  mrg                  hence the possible division by div9. */
    338      1.1  mrg               div12 = div11 * div11; /* 2^(-2^12) */
    339      1.1  mrg               div13 = div12 * div12; /* 2^(-2^13) */
    340      1.1  mrg               if (ABS (x) <= div13)
    341      1.1  mrg                 {
    342      1.1  mrg                   x /= div13; /* exact */
    343      1.1  mrg                   shift_exp -= 8192;
    344      1.1  mrg                   mpfr_mul_2si (t, t, 8192, MPFR_RNDZ);
    345      1.1  mrg                 }
    346      1.1  mrg               if (ABS (x) <= div12)
    347      1.1  mrg                 {
    348      1.1  mrg                   x /= div12; /* exact */
    349      1.1  mrg                   shift_exp -= 4096;
    350      1.1  mrg                   mpfr_mul_2si (t, t, 4096, MPFR_RNDZ);
    351      1.1  mrg                 }
    352      1.1  mrg               if (ABS (x) <= div11)
    353      1.1  mrg                 {
    354      1.1  mrg                   x /= div11; /* exact */
    355      1.1  mrg                   shift_exp -= 2048;
    356      1.1  mrg                   mpfr_mul_2si (t, t, 2048, MPFR_RNDZ);
    357      1.1  mrg                 }
    358      1.1  mrg               if (ABS (x) <= div10)
    359      1.1  mrg                 {
    360      1.1  mrg                   x /= div10; /* exact */
    361      1.1  mrg                   shift_exp -= 1024;
    362      1.1  mrg                   mpfr_mul_2si (t, t, 1024, MPFR_RNDZ);
    363      1.1  mrg                 }
    364      1.1  mrg               if (ABS(x) <= div9)
    365      1.1  mrg                 {
    366      1.1  mrg                   x /= div9;  /* exact */
    367      1.1  mrg                   shift_exp -= 512;
    368      1.1  mrg                   mpfr_mul_2si (t, t, 512, MPFR_RNDZ);
    369      1.1  mrg                 }
    370      1.1  mrg             }
    371      1.1  mrg           else /* no underflow */
    372      1.1  mrg             {
    373      1.1  mrg               inexact = mpfr_set_d (u, (double) x, MPFR_RNDZ);
    374      1.1  mrg               MPFR_ASSERTD (inexact == 0);
    375      1.1  mrg               if (mpfr_add (t, t, u, MPFR_RNDZ) != 0)
    376      1.1  mrg                 {
    377      1.1  mrg                   if (!mpfr_number_p (t))
    378      1.1  mrg                     break;
    379      1.1  mrg                   /* Inexact. This cannot happen unless the C implementation
    380      1.1  mrg                      "lies" on the precision or when long doubles are
    381  1.1.1.3  mrg                      implemented with FP expansions like double-double on
    382  1.1.1.3  mrg                      PowerPC. */
    383      1.1  mrg                   if (MPFR_PREC (t) != MPFR_PREC (r) + 1)
    384      1.1  mrg                     {
    385      1.1  mrg                       /* We assume that MPFR_PREC (r) < MPFR_PREC_MAX.
    386      1.1  mrg                          The precision MPFR_PREC (r) + 1 allows us to
    387      1.1  mrg                          deduce the rounding bit and the sticky bit. */
    388      1.1  mrg                       mpfr_set_prec (t, MPFR_PREC (r) + 1);
    389      1.1  mrg                       goto convert;
    390      1.1  mrg                     }
    391      1.1  mrg                   else
    392      1.1  mrg                     {
    393      1.1  mrg                       mp_limb_t *tp;
    394      1.1  mrg                       int rb_mask;
    395      1.1  mrg 
    396      1.1  mrg                       /* Since mpfr_add was inexact, the sticky bit is 1. */
    397      1.1  mrg                       tp = MPFR_MANT (t);
    398      1.1  mrg                       rb_mask = MPFR_LIMB_ONE <<
    399      1.1  mrg                         (GMP_NUMB_BITS - 1 -
    400      1.1  mrg                          (MPFR_PREC (r) & (GMP_NUMB_BITS - 1)));
    401      1.1  mrg                       if (rnd_mode == MPFR_RNDN)
    402      1.1  mrg                         rnd_mode = (*tp & rb_mask) ^ MPFR_IS_NEG (t) ?
    403      1.1  mrg                           MPFR_RNDU : MPFR_RNDD;
    404      1.1  mrg                       *tp |= rb_mask;
    405      1.1  mrg                       break;
    406      1.1  mrg                     }
    407      1.1  mrg                 }
    408      1.1  mrg               x -= (long double) mpfr_get_d1 (u); /* exact */
    409      1.1  mrg             }
    410      1.1  mrg         }
    411      1.1  mrg     }
    412      1.1  mrg   inexact = mpfr_mul_2si (r, t, shift_exp, rnd_mode);
    413      1.1  mrg   mpfr_clear (t);
    414      1.1  mrg   mpfr_clear (u);
    415      1.1  mrg 
    416      1.1  mrg   MPFR_SAVE_EXPO_FREE (expo);
    417      1.1  mrg   return mpfr_check_range (r, inexact, rnd_mode);
    418      1.1  mrg }
    419      1.1  mrg 
    420      1.1  mrg #endif
    421