Home | History | Annotate | Line # | Download | only in tests
      1      1.1  mrg /* Test file for mpfr_sub1sp.
      2      1.1  mrg 
      3  1.1.1.6  mrg Copyright 2003-2023 Free Software Foundation, Inc.
      4  1.1.1.3  mrg Contributed by the AriC and Caramba projects, INRIA.
      5      1.1  mrg 
      6      1.1  mrg This file is part of the GNU MPFR Library.
      7      1.1  mrg 
      8      1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9      1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     10      1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     11      1.1  mrg option) any later version.
     12      1.1  mrg 
     13      1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14      1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15      1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16      1.1  mrg License for more details.
     17      1.1  mrg 
     18      1.1  mrg You should have received a copy of the GNU Lesser General Public License
     19      1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20  1.1.1.5  mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21      1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22      1.1  mrg 
     23      1.1  mrg #include "mpfr-test.h"
     24      1.1  mrg 
     25      1.1  mrg static void check_special (void);
     26      1.1  mrg static void check_random (mpfr_prec_t p);
     27  1.1.1.4  mrg static void check_underflow (mpfr_prec_t p);
     28  1.1.1.4  mrg static void check_corner (mpfr_prec_t p);
     29  1.1.1.4  mrg 
     30  1.1.1.4  mrg static void
     31  1.1.1.4  mrg bug20170109 (void)
     32  1.1.1.4  mrg {
     33  1.1.1.4  mrg   mpfr_t a, b, c;
     34  1.1.1.4  mrg 
     35  1.1.1.4  mrg   mpfr_init2 (a, 111);
     36  1.1.1.4  mrg   mpfr_init2 (b, 111);
     37  1.1.1.4  mrg   mpfr_init2 (c, 111);
     38  1.1.1.4  mrg   mpfr_set_str_binary (b, "0.110010010000111111011010101000100010000101101000110000100011010011000100110001100110001010001011100000001101110E1");
     39  1.1.1.4  mrg   mpfr_set_str_binary (c, "0.111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111E-63");
     40  1.1.1.4  mrg   mpfr_sub (a, b, c, MPFR_RNDN);
     41  1.1.1.4  mrg   mpfr_set_str_binary (b, "0.110010010000111111011010101000100010000101101000110000100011001111000100110001100110001010001011100000001101110E1");
     42  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_equal_p (a, b));
     43  1.1.1.4  mrg   mpfr_clear (a);
     44  1.1.1.4  mrg   mpfr_clear (b);
     45  1.1.1.4  mrg   mpfr_clear (c);
     46  1.1.1.4  mrg }
     47  1.1.1.4  mrg 
     48  1.1.1.4  mrg /* check mpfr_sub1sp1 when:
     49  1.1.1.4  mrg    (1) p = GMP_NUMB_BITS-1, d = GMP_NUMB_BITS and bp[0] = MPFR_LIMB_HIGHBIT
     50  1.1.1.4  mrg    (2) p = 2*GMP_NUMB_BITS-1, d = 2*GMP_NUMB_BITS and b = 1000...000
     51  1.1.1.4  mrg    (3) p = 3*GMP_NUMB_BITS-1, d = 3*GMP_NUMB_BITS and b = 1000...000
     52  1.1.1.4  mrg */
     53  1.1.1.4  mrg static void
     54  1.1.1.4  mrg test20170208 (void)
     55  1.1.1.4  mrg {
     56  1.1.1.4  mrg   mpfr_t a, b, c;
     57  1.1.1.4  mrg   int inex;
     58  1.1.1.4  mrg 
     59  1.1.1.4  mrg   mpfr_inits2 (GMP_NUMB_BITS - 1, a, b, c, (mpfr_ptr) 0);
     60  1.1.1.4  mrg 
     61  1.1.1.4  mrg   /* test (1) */
     62  1.1.1.4  mrg   mpfr_set_ui_2exp (b, 1, GMP_NUMB_BITS, MPFR_RNDN);
     63  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
     64  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
     65  1.1.1.4  mrg   /* b-c = 2^GMP_NUMB_BITS-1 which has GMP_NUMB_BITS bits, thus we should
     66  1.1.1.4  mrg      round to 2^GMP_NUMB_BITS (even rule) */
     67  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, GMP_NUMB_BITS) == 0);
     68  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
     69  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
     70  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, GMP_NUMB_BITS) == 0);
     71  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
     72  1.1.1.4  mrg 
     73  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
     74  1.1.1.4  mrg   mpfr_nextbelow (c);
     75  1.1.1.4  mrg   /* now c = 2 - 2^(1-GMP_NUMB_BITS) */
     76  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
     77  1.1.1.4  mrg   /* b-c = 2^GMP_NUMB_BITS-2+2^(1-GMP_NUMB_BITS), which should
     78  1.1.1.4  mrg      round to 2^GMP_NUMB_BITS-2. We check by directly inspecting the bit
     79  1.1.1.4  mrg      field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
     80  1.1.1.4  mrg      than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
     81  1.1.1.4  mrg      to construct the expected result. */
     82  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
     83  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == GMP_NUMB_BITS);
     84  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
     85  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
     86  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
     87  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == GMP_NUMB_BITS);
     88  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
     89  1.1.1.4  mrg 
     90  1.1.1.4  mrg   /* test (2) */
     91  1.1.1.4  mrg   mpfr_set_prec (a, 2 * GMP_NUMB_BITS - 1);
     92  1.1.1.4  mrg   mpfr_set_prec (b, 2 * GMP_NUMB_BITS - 1);
     93  1.1.1.4  mrg   mpfr_set_prec (c, 2 * GMP_NUMB_BITS - 1);
     94  1.1.1.4  mrg   mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
     95  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
     96  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
     97  1.1.1.4  mrg   /* b-c = 2^(2*GMP_NUMB_BITS)-1 which has 2*GMP_NUMB_BITS bits, thus we should
     98  1.1.1.4  mrg      round to 2^(2*GMP_NUMB_BITS) (even rule) */
     99  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 2 * GMP_NUMB_BITS) == 0);
    100  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
    101  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
    102  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 2 * GMP_NUMB_BITS) == 0);
    103  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
    104  1.1.1.4  mrg 
    105  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
    106  1.1.1.4  mrg   mpfr_nextbelow (c);
    107  1.1.1.4  mrg   /* now c = 2 - 2^(1-2*GMP_NUMB_BITS) */
    108  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
    109  1.1.1.4  mrg   /* b-c = 2^(2*GMP_NUMB_BITS)-2+2^(1-2*GMP_NUMB_BITS), which should
    110  1.1.1.4  mrg      round to 2^(2*GMP_NUMB_BITS)-2. We check by directly inspecting the bit
    111  1.1.1.4  mrg      field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
    112  1.1.1.4  mrg      than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
    113  1.1.1.4  mrg      to construct the expected result. */
    114  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
    115  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
    116  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == 2 * GMP_NUMB_BITS);
    117  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
    118  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
    119  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
    120  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
    121  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == 2 * GMP_NUMB_BITS);
    122  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
    123  1.1.1.4  mrg 
    124  1.1.1.4  mrg   /* test (3) */
    125  1.1.1.4  mrg   mpfr_set_prec (a, 3 * GMP_NUMB_BITS - 1);
    126  1.1.1.4  mrg   mpfr_set_prec (b, 3 * GMP_NUMB_BITS - 1);
    127  1.1.1.4  mrg   mpfr_set_prec (c, 3 * GMP_NUMB_BITS - 1);
    128  1.1.1.4  mrg   mpfr_set_ui_2exp (b, 1, 3 * GMP_NUMB_BITS, MPFR_RNDN);
    129  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
    130  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
    131  1.1.1.4  mrg   /* b-c = 2^(3*GMP_NUMB_BITS)-1 which has 3*GMP_NUMB_BITS bits, thus we should
    132  1.1.1.4  mrg      round to 3^(2*GMP_NUMB_BITS) (even rule) */
    133  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 3 * GMP_NUMB_BITS) == 0);
    134  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
    135  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
    136  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, 3 * GMP_NUMB_BITS) == 0);
    137  1.1.1.4  mrg   MPFR_ASSERTN(inex > 0);
    138  1.1.1.4  mrg 
    139  1.1.1.4  mrg   mpfr_set_ui_2exp (c, 2, 0, MPFR_RNDN);
    140  1.1.1.4  mrg   mpfr_nextbelow (c);
    141  1.1.1.4  mrg   /* now c = 2 - 2^(1-3*GMP_NUMB_BITS) */
    142  1.1.1.4  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
    143  1.1.1.4  mrg   /* b-c = 2^(3*GMP_NUMB_BITS)-2+2^(1-3*GMP_NUMB_BITS), which should
    144  1.1.1.4  mrg      round to 2^(3*GMP_NUMB_BITS)-2. We check by directly inspecting the bit
    145  1.1.1.4  mrg      field of a, since mpfr_cmp_ui might not work if unsigned long is shorter
    146  1.1.1.4  mrg      than mp_limb_t, and we don't want to use mpfr_add_ui or mpfr_sub_ui
    147  1.1.1.4  mrg      to construct the expected result. */
    148  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[2] == (mp_limb_t) -1);
    149  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
    150  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
    151  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == 3 * GMP_NUMB_BITS);
    152  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
    153  1.1.1.4  mrg   inex = mpfr_sub1sp (a, b, c, MPFR_RNDN);
    154  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[2] == (mp_limb_t) -1);
    155  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[1] == (mp_limb_t) -1);
    156  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_MANT(a)[0] == (mp_limb_t) -2);
    157  1.1.1.4  mrg   MPFR_ASSERTN(MPFR_EXP(a) == 3 * GMP_NUMB_BITS);
    158  1.1.1.4  mrg   MPFR_ASSERTN(inex < 0);
    159  1.1.1.4  mrg 
    160  1.1.1.4  mrg   mpfr_clears (a, b, c, (mpfr_ptr) 0);
    161  1.1.1.4  mrg }
    162  1.1.1.4  mrg 
    163  1.1.1.4  mrg static void
    164  1.1.1.4  mrg compare_sub_sub1sp (void)
    165  1.1.1.4  mrg {
    166  1.1.1.4  mrg   mpfr_t a, b, c, a_ref;
    167  1.1.1.4  mrg   mpfr_prec_t p;
    168  1.1.1.4  mrg   unsigned long d;
    169  1.1.1.4  mrg   int i, inex_ref, inex;
    170  1.1.1.4  mrg   int r;
    171  1.1.1.4  mrg 
    172  1.1.1.4  mrg   for (p = 1; p <= 3*GMP_NUMB_BITS; p++)
    173  1.1.1.4  mrg     {
    174  1.1.1.4  mrg       mpfr_inits2 (p, a, b, c, a_ref, (mpfr_ptr) 0);
    175  1.1.1.4  mrg       for (d = 0; d <= p + 2; d++)
    176  1.1.1.4  mrg         {
    177  1.1.1.4  mrg           /* EXP(b) - EXP(c) = d */
    178  1.1.1.4  mrg           for (i = 0; i < 4; i++)
    179  1.1.1.4  mrg             {
    180  1.1.1.4  mrg               /* for i even, b is the smallest number, for b odd the largest */
    181  1.1.1.4  mrg               mpfr_set_ui_2exp (b, 1, d, MPFR_RNDN);
    182  1.1.1.4  mrg               if (i & 1)
    183  1.1.1.4  mrg                 {
    184  1.1.1.5  mrg                   mpfr_mul_2ui (b, b, 1, MPFR_RNDN);
    185  1.1.1.4  mrg                   mpfr_nextbelow (b);
    186  1.1.1.4  mrg                 }
    187  1.1.1.4  mrg               mpfr_set_ui_2exp (c, 1, 0, MPFR_RNDN);
    188  1.1.1.4  mrg               if (i & 2)
    189  1.1.1.4  mrg                 {
    190  1.1.1.5  mrg                   mpfr_mul_2ui (c, c, 1, MPFR_RNDN);
    191  1.1.1.4  mrg                   mpfr_nextbelow (c);
    192  1.1.1.4  mrg                 }
    193  1.1.1.4  mrg               RND_LOOP_NO_RNDF (r)
    194  1.1.1.4  mrg                 {
    195  1.1.1.4  mrg                   /* increase the precision of b to ensure sub1sp is not used */
    196  1.1.1.4  mrg                   mpfr_prec_round (b, p + 1, MPFR_RNDN);
    197  1.1.1.4  mrg                   inex_ref = mpfr_sub (a_ref, b, c, (mpfr_rnd_t) r);
    198  1.1.1.4  mrg                   inex = mpfr_prec_round (b, p, MPFR_RNDN);
    199  1.1.1.4  mrg                   MPFR_ASSERTN(inex == 0);
    200  1.1.1.4  mrg                   inex = mpfr_sub1sp (a, b, c, (mpfr_rnd_t) r);
    201  1.1.1.4  mrg                   if (inex != inex_ref)
    202  1.1.1.4  mrg                     {
    203  1.1.1.4  mrg                       printf ("mpfr_sub and mpfr_sub1sp differ for r=%s\n",
    204  1.1.1.4  mrg                               mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    205  1.1.1.4  mrg                       printf ("b="); mpfr_dump (b);
    206  1.1.1.4  mrg                       printf ("c="); mpfr_dump (c);
    207  1.1.1.4  mrg                       printf ("expected inex=%d and ", inex_ref);
    208  1.1.1.4  mrg                       mpfr_dump (a_ref);
    209  1.1.1.4  mrg                       printf ("got      inex=%d and ", inex);
    210  1.1.1.4  mrg                       mpfr_dump (a);
    211  1.1.1.4  mrg                       exit (1);
    212  1.1.1.4  mrg                     }
    213  1.1.1.4  mrg                   MPFR_ASSERTN(mpfr_equal_p (a, a_ref));
    214  1.1.1.4  mrg                 }
    215  1.1.1.4  mrg             }
    216  1.1.1.4  mrg         }
    217  1.1.1.4  mrg       mpfr_clears (a, b, c, a_ref, (mpfr_ptr) 0);
    218  1.1.1.4  mrg     }
    219  1.1.1.4  mrg }
    220  1.1.1.4  mrg 
    221  1.1.1.4  mrg static void
    222  1.1.1.4  mrg bug20171213 (void)
    223  1.1.1.4  mrg {
    224  1.1.1.4  mrg   mpfr_t a, b, c;
    225  1.1.1.4  mrg 
    226  1.1.1.4  mrg   mpfr_init2 (a, 127);
    227  1.1.1.4  mrg   mpfr_init2 (b, 127);
    228  1.1.1.4  mrg   mpfr_init2 (c, 127);
    229  1.1.1.4  mrg   mpfr_set_str_binary (b, "0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
    230  1.1.1.4  mrg   mpfr_set_str_binary (c, "0.1000011010111101100101100110101111111001011001010000110000000000000000000000000000000000000000000000000000000000000000000000000E-74");
    231  1.1.1.4  mrg   mpfr_sub (a, b, c, MPFR_RNDN);
    232  1.1.1.4  mrg   mpfr_set_str_binary (b, "0.1111111111111111111111111111111111111111111111111111111111111111111111111101111001010000100110100110010100000001101001101011110E0");
    233  1.1.1.4  mrg   MPFR_ASSERTN(mpfr_equal_p (a, b));
    234  1.1.1.4  mrg   mpfr_clear (a);
    235  1.1.1.4  mrg   mpfr_clear (b);
    236  1.1.1.4  mrg   mpfr_clear (c);
    237  1.1.1.4  mrg }
    238  1.1.1.4  mrg 
    239  1.1.1.4  mrg /* generic test for bug20171213:
    240  1.1.1.4  mrg    b = 1.0 with precision p
    241  1.1.1.4  mrg    c = 0.1xxx110...0E-e with precision p, with e >= 1, such that the part 1xxx1 has
    242  1.1.1.4  mrg        exactly p+1-e bits, thus b-c = 0.111..01... is exact on p+1 bits.
    243  1.1.1.4  mrg    Due to the round-to-even rule, b-c should be rounded to 0.111..0.
    244  1.1.1.4  mrg */
    245  1.1.1.4  mrg static void
    246  1.1.1.4  mrg bug20171213_gen (mpfr_prec_t pmax)
    247  1.1.1.4  mrg {
    248  1.1.1.4  mrg   mpfr_prec_t p;
    249  1.1.1.4  mrg   mpfr_exp_t e;
    250  1.1.1.4  mrg   mpfr_t a, b, c, d;
    251  1.1.1.4  mrg 
    252  1.1.1.4  mrg   for (p = MPFR_PREC_MIN; p <= pmax; p++)
    253  1.1.1.4  mrg     {
    254  1.1.1.4  mrg       for (e = 1; e < p; e++)
    255  1.1.1.4  mrg         {
    256  1.1.1.4  mrg           mpfr_init2 (a, p);
    257  1.1.1.4  mrg           mpfr_init2 (b, p);
    258  1.1.1.4  mrg           mpfr_init2 (c, p);
    259  1.1.1.4  mrg           mpfr_init2 (d, p);
    260  1.1.1.4  mrg           mpfr_set_ui (b, 1, MPFR_RNDN);
    261  1.1.1.4  mrg           mpfr_set_ui_2exp (c, 1, p + 1 - e, MPFR_RNDN); /* c = 2^(p + 1 - e) */
    262  1.1.1.4  mrg           mpfr_sub_ui (c, c, 1, MPFR_RNDN); /* c = 2^(p + 1 - e) - 1 */
    263  1.1.1.5  mrg           mpfr_div_2ui (c, c, p + 1, MPFR_RNDN); /* c = 2^(-e) - 2^(-p-1) */
    264  1.1.1.4  mrg           /* the exact difference is 1 - 2^(-e) + 2^(-p-1) */
    265  1.1.1.4  mrg           mpfr_sub (a, b, c, MPFR_RNDN);
    266  1.1.1.4  mrg           /* check that a = 1 - 2^(-e) */
    267  1.1.1.4  mrg           mpfr_set_ui_2exp (d, 1, e, MPFR_RNDN); /* b = 2^e */
    268  1.1.1.4  mrg           mpfr_sub_ui (d, d, 1, MPFR_RNDN);      /* b = 2^e - 1 */
    269  1.1.1.5  mrg           mpfr_div_2ui (d, d, e, MPFR_RNDN);    /* b = 1 - 2^(-e) */
    270  1.1.1.4  mrg           if (! mpfr_equal_p (a, d))
    271  1.1.1.4  mrg             {
    272  1.1.1.5  mrg               printf ("bug20171213_gen failed for p=%ld, e=%ld\n",
    273  1.1.1.5  mrg                       (long) p, (long) e);
    274  1.1.1.4  mrg               printf ("b="); mpfr_dump (b);
    275  1.1.1.4  mrg               printf ("c="); mpfr_dump (c);
    276  1.1.1.4  mrg               printf ("got      a="); mpfr_dump (a);
    277  1.1.1.4  mrg               printf ("expected d="); mpfr_dump (d);
    278  1.1.1.4  mrg               exit (1);
    279  1.1.1.4  mrg             }
    280  1.1.1.4  mrg           mpfr_clear (a);
    281  1.1.1.4  mrg           mpfr_clear (b);
    282  1.1.1.4  mrg           mpfr_clear (c);
    283  1.1.1.4  mrg           mpfr_clear (d);
    284  1.1.1.4  mrg         }
    285  1.1.1.4  mrg     }
    286  1.1.1.4  mrg }
    287      1.1  mrg 
    288  1.1.1.5  mrg static void
    289  1.1.1.5  mrg coverage (void)
    290  1.1.1.5  mrg {
    291  1.1.1.5  mrg   mpfr_t a, b, c, d, u;
    292  1.1.1.5  mrg   int inex;
    293  1.1.1.5  mrg 
    294  1.1.1.5  mrg   /* coverage test in mpfr_sub1sp: case d=1, limb > MPFR_LIMB_HIGHBIT, RNDF
    295  1.1.1.5  mrg      and also RNDZ */
    296  1.1.1.5  mrg   mpfr_init2 (a, 3 * GMP_NUMB_BITS);
    297  1.1.1.5  mrg   mpfr_init2 (b, 3 * GMP_NUMB_BITS);
    298  1.1.1.5  mrg   mpfr_init2 (c, 3 * GMP_NUMB_BITS);
    299  1.1.1.5  mrg   mpfr_init2 (d, 3 * GMP_NUMB_BITS);
    300  1.1.1.5  mrg   mpfr_init2 (u, 3 * GMP_NUMB_BITS);
    301  1.1.1.5  mrg   mpfr_set_ui (b, 1, MPFR_RNDN);
    302  1.1.1.5  mrg   mpfr_nextbelow (b); /* b = 1 - 2^(-p) */
    303  1.1.1.5  mrg   mpfr_set_prec (c, GMP_NUMB_BITS);
    304  1.1.1.5  mrg   mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);
    305  1.1.1.5  mrg   mpfr_nextbelow (c);
    306  1.1.1.5  mrg   mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) */
    307  1.1.1.5  mrg   mpfr_prec_round (c, 3 * GMP_NUMB_BITS, MPFR_RNDN);
    308  1.1.1.5  mrg   mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) - 2^(-p-1) */
    309  1.1.1.5  mrg   /* b-c = c */
    310  1.1.1.5  mrg   mpfr_sub (a, b, c, MPFR_RNDF);
    311  1.1.1.5  mrg   mpfr_sub (d, b, c, MPFR_RNDD);
    312  1.1.1.5  mrg   mpfr_sub (u, b, c, MPFR_RNDU);
    313  1.1.1.5  mrg   /* check a = d or u */
    314  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_equal_p (a, d) || mpfr_equal_p (a, u));
    315  1.1.1.5  mrg 
    316  1.1.1.5  mrg   /* coverage test in mpfr_sub1sp: case d=p, RNDN, sb = 0, significand of b
    317  1.1.1.5  mrg      is even but b<>2^e, (case 1e) */
    318  1.1.1.5  mrg   mpfr_set_prec (a, 3 * GMP_NUMB_BITS);
    319  1.1.1.5  mrg   mpfr_set_prec (b, 3 * GMP_NUMB_BITS);
    320  1.1.1.5  mrg   mpfr_set_prec (c, 3 * GMP_NUMB_BITS);
    321  1.1.1.5  mrg   mpfr_set_ui (b, 1, MPFR_RNDN);
    322  1.1.1.5  mrg   mpfr_nextabove (b);
    323  1.1.1.5  mrg   mpfr_nextabove (b);
    324  1.1.1.5  mrg   mpfr_set_ui_2exp (c, 1, -3 * GMP_NUMB_BITS, MPFR_RNDN);
    325  1.1.1.5  mrg   inex = mpfr_sub (a, b, c, MPFR_RNDN);
    326  1.1.1.5  mrg   MPFR_ASSERTN(inex > 0);
    327  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_equal_p (a, b));
    328  1.1.1.5  mrg 
    329  1.1.1.5  mrg   mpfr_clear (a);
    330  1.1.1.5  mrg   mpfr_clear (b);
    331  1.1.1.5  mrg   mpfr_clear (c);
    332  1.1.1.5  mrg   mpfr_clear (d);
    333  1.1.1.5  mrg   mpfr_clear (u);
    334  1.1.1.5  mrg }
    335  1.1.1.5  mrg 
    336  1.1.1.5  mrg /* bug in mpfr_sub1sp1n, made generic */
    337  1.1.1.5  mrg static void
    338  1.1.1.5  mrg bug20180217 (mpfr_prec_t pmax)
    339  1.1.1.5  mrg {
    340  1.1.1.5  mrg   mpfr_t a, b, c;
    341  1.1.1.5  mrg   int inex;
    342  1.1.1.5  mrg   mpfr_prec_t p;
    343  1.1.1.5  mrg 
    344  1.1.1.5  mrg   for (p = MPFR_PREC_MIN; p <= pmax; p++)
    345  1.1.1.5  mrg     {
    346  1.1.1.5  mrg       mpfr_init2 (a, p);
    347  1.1.1.5  mrg       mpfr_init2 (b, p);
    348  1.1.1.5  mrg       mpfr_init2 (c, p);
    349  1.1.1.5  mrg       mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
    350  1.1.1.5  mrg       mpfr_set_ui_2exp (c, 1, -p-1, MPFR_RNDN); /* c = 2^(-p-1) */
    351  1.1.1.5  mrg       /* a - b = 1 - 2^(-p-1) and should be rounded to 1 (case 2f of
    352  1.1.1.5  mrg          mpfr_sub1sp) */
    353  1.1.1.5  mrg       inex = mpfr_sub (a, b, c, MPFR_RNDN);
    354  1.1.1.5  mrg       MPFR_ASSERTN(inex > 0);
    355  1.1.1.5  mrg       MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
    356  1.1.1.5  mrg       /* check also when a=b */
    357  1.1.1.5  mrg       mpfr_set_ui (a, 1, MPFR_RNDN);
    358  1.1.1.5  mrg       inex = mpfr_sub (a, a, c, MPFR_RNDN);
    359  1.1.1.5  mrg       MPFR_ASSERTN(inex > 0);
    360  1.1.1.5  mrg       MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
    361  1.1.1.5  mrg       /* and when a=c */
    362  1.1.1.5  mrg       mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
    363  1.1.1.5  mrg       mpfr_set_ui_2exp (a, 1, -p-1, MPFR_RNDN);
    364  1.1.1.5  mrg       inex = mpfr_sub (a, b, a, MPFR_RNDN);
    365  1.1.1.5  mrg       MPFR_ASSERTN(inex > 0);
    366  1.1.1.5  mrg       MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
    367  1.1.1.5  mrg       mpfr_clear (a);
    368  1.1.1.5  mrg       mpfr_clear (b);
    369  1.1.1.5  mrg       mpfr_clear (c);
    370  1.1.1.5  mrg     }
    371  1.1.1.5  mrg }
    372  1.1.1.5  mrg 
    373  1.1.1.5  mrg /* bug in revision 12985 with tlog and GMP_CHECK_RANDOMIZE=1534111552615050
    374  1.1.1.5  mrg    (introduced in revision 12242, does not affect the 4.0 branch) */
    375  1.1.1.5  mrg static void
    376  1.1.1.5  mrg bug20180813 (void)
    377  1.1.1.5  mrg {
    378  1.1.1.5  mrg   mpfr_t a, b, c;
    379  1.1.1.5  mrg 
    380  1.1.1.5  mrg   mpfr_init2 (a, 194);
    381  1.1.1.5  mrg   mpfr_init2 (b, 194);
    382  1.1.1.5  mrg   mpfr_init2 (c, 194);
    383  1.1.1.5  mrg   mpfr_set_str_binary (b, "0.10000111101000100000010000100010110111011100110100000101100111000010101000110110010101011101101011110110001000111001000010110010111010010100011011010100001010001110000101000010101110100110001000E7");
    384  1.1.1.5  mrg   mpfr_set_str_binary (c, "0.10000000000000000100001111010001000000100001000101101110111001101000001011001110000101010001101100101010111011010111101100010001110010000101100101110100101000110110101000010100011100001010000101E24");
    385  1.1.1.5  mrg   mpfr_sub (a, b, c, MPFR_RNDN);
    386  1.1.1.5  mrg   mpfr_set_str_binary (b, "-0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111E23");
    387  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_equal_p (a, b));
    388  1.1.1.5  mrg   mpfr_clear (a);
    389  1.1.1.5  mrg   mpfr_clear (b);
    390  1.1.1.5  mrg   mpfr_clear (c);
    391  1.1.1.5  mrg }
    392  1.1.1.5  mrg 
    393  1.1.1.5  mrg /* bug in revision 13599 with tatan and GMP_CHECK_RANDOMIZE=1567609230659336:
    394  1.1.1.5  mrg    the values are equal, but the ternary value differs between sub1 and sub1sp
    395  1.1.1.5  mrg    (bug introduced with mpfr_sub1sp2n, does not affect the 4.0 branch) */
    396  1.1.1.5  mrg static void
    397  1.1.1.5  mrg bug20190904 (void)
    398  1.1.1.5  mrg {
    399  1.1.1.5  mrg   mpfr_t a, b, c;
    400  1.1.1.5  mrg   int ret;
    401  1.1.1.5  mrg 
    402  1.1.1.5  mrg   mpfr_init2 (a, 128);
    403  1.1.1.5  mrg   mpfr_init2 (b, 128);
    404  1.1.1.5  mrg   mpfr_init2 (c, 128);
    405  1.1.1.5  mrg   mpfr_set_str_binary (b, "0.11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101110000000110111000001110011010001E1");
    406  1.1.1.5  mrg   mpfr_set_str_binary (c, "0.10010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010010000000000000000000000E-102");
    407  1.1.1.5  mrg   ret = mpfr_sub (a, b, c, MPFR_RNDN);
    408  1.1.1.5  mrg   mpfr_set_str_binary (b, "0.11001001000011111101101010100010001000010110100011000010001101001100010011000110011000101000101101111111101111000001110011010001E1");
    409  1.1.1.5  mrg   MPFR_ASSERTN(mpfr_equal_p (a, b));
    410  1.1.1.5  mrg   MPFR_ASSERTN(ret > 0);
    411  1.1.1.5  mrg   mpfr_clear (a);
    412  1.1.1.5  mrg   mpfr_clear (b);
    413  1.1.1.5  mrg   mpfr_clear (c);
    414  1.1.1.5  mrg }
    415  1.1.1.5  mrg 
    416      1.1  mrg int
    417      1.1  mrg main (void)
    418      1.1  mrg {
    419      1.1  mrg   mpfr_prec_t p;
    420      1.1  mrg 
    421      1.1  mrg   tests_start_mpfr ();
    422      1.1  mrg 
    423  1.1.1.5  mrg   bug20190904 ();
    424  1.1.1.5  mrg   bug20180813 ();
    425  1.1.1.5  mrg   bug20180217 (1024);
    426  1.1.1.5  mrg   coverage ();
    427  1.1.1.4  mrg   compare_sub_sub1sp ();
    428  1.1.1.4  mrg   test20170208 ();
    429  1.1.1.4  mrg   bug20170109 ();
    430  1.1.1.4  mrg   bug20171213 ();
    431  1.1.1.4  mrg   bug20171213_gen (256);
    432      1.1  mrg   check_special ();
    433  1.1.1.4  mrg   for (p = MPFR_PREC_MIN ; p < 200 ; p++)
    434  1.1.1.4  mrg     {
    435  1.1.1.4  mrg       check_underflow (p);
    436  1.1.1.4  mrg       check_random (p);
    437  1.1.1.4  mrg       check_corner (p);
    438  1.1.1.4  mrg     }
    439      1.1  mrg 
    440      1.1  mrg   tests_end_mpfr ();
    441      1.1  mrg   return 0;
    442      1.1  mrg }
    443      1.1  mrg 
    444  1.1.1.2  mrg #define STD_ERROR                                                       \
    445  1.1.1.2  mrg   do                                                                    \
    446  1.1.1.2  mrg     {                                                                   \
    447  1.1.1.2  mrg       printf("ERROR: for %s and p=%lu and i=%d:\nY=",                   \
    448  1.1.1.2  mrg              mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
    449  1.1.1.4  mrg       mpfr_dump (y);                                                    \
    450  1.1.1.4  mrg       printf ("Z="); mpfr_dump (z);                                     \
    451  1.1.1.4  mrg       printf ("Expected: "); mpfr_dump (x2);                            \
    452  1.1.1.4  mrg       printf ("Got :     "); mpfr_dump (x);                             \
    453  1.1.1.4  mrg       abort();                                                          \
    454  1.1.1.2  mrg     }                                                                   \
    455  1.1.1.2  mrg  while (0)
    456  1.1.1.2  mrg 
    457  1.1.1.2  mrg #define STD_ERROR2                                                      \
    458  1.1.1.2  mrg   do                                                                    \
    459  1.1.1.2  mrg     {                                                                   \
    460  1.1.1.2  mrg       printf("ERROR: for %s and p=%lu and i=%d:\nY=",                   \
    461  1.1.1.2  mrg              mpfr_print_rnd_mode ((mpfr_rnd_t) r), (unsigned long) p, i); \
    462  1.1.1.4  mrg       mpfr_dump (y);                                                    \
    463  1.1.1.4  mrg       printf ("Z="); mpfr_dump (z);                                     \
    464  1.1.1.4  mrg       printf ("Expected: "); mpfr_dump (x2);                            \
    465  1.1.1.4  mrg       printf ("Got :     "); mpfr_dump (x);                             \
    466  1.1.1.4  mrg       printf ("Wrong inexact flag. Expected %d. Got %d\n",              \
    467  1.1.1.4  mrg               inexact1, inexact2);                                      \
    468  1.1.1.2  mrg       exit(1);                                                          \
    469  1.1.1.2  mrg     }                                                                   \
    470  1.1.1.2  mrg  while (0)
    471      1.1  mrg 
    472      1.1  mrg static void
    473      1.1  mrg check_random (mpfr_prec_t p)
    474      1.1  mrg {
    475      1.1  mrg   mpfr_t x,y,z,x2;
    476      1.1  mrg   int r;
    477      1.1  mrg   int i, inexact1, inexact2;
    478      1.1  mrg 
    479      1.1  mrg   mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0);
    480      1.1  mrg 
    481      1.1  mrg   for (i = 0 ; i < 500 ; i++)
    482      1.1  mrg     {
    483      1.1  mrg       mpfr_urandomb (y, RANDS);
    484      1.1  mrg       mpfr_urandomb (z, RANDS);
    485      1.1  mrg       if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z))
    486  1.1.1.6  mrg         RND_LOOP (r)
    487      1.1  mrg           {
    488  1.1.1.4  mrg             if (r == MPFR_RNDF)
    489  1.1.1.4  mrg               continue; /* mpfr_sub1 and mpfr_sub1sp could differ,
    490  1.1.1.4  mrg                            and inexact makes no sense */
    491      1.1  mrg             inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    492      1.1  mrg             inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    493      1.1  mrg             if (mpfr_cmp(x, x2))
    494      1.1  mrg               STD_ERROR;
    495      1.1  mrg             if (inexact1 != inexact2)
    496      1.1  mrg               STD_ERROR2;
    497      1.1  mrg           }
    498      1.1  mrg     }
    499      1.1  mrg 
    500      1.1  mrg   mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
    501      1.1  mrg }
    502      1.1  mrg 
    503      1.1  mrg static void
    504      1.1  mrg check_special (void)
    505      1.1  mrg {
    506      1.1  mrg   mpfr_t x,y,z,x2;
    507      1.1  mrg   int r;
    508      1.1  mrg   mpfr_prec_t p;
    509      1.1  mrg   int i = -1, inexact1, inexact2;
    510      1.1  mrg   mpfr_exp_t es;
    511      1.1  mrg 
    512      1.1  mrg   mpfr_inits (x, y, z, x2, (mpfr_ptr) 0);
    513      1.1  mrg 
    514  1.1.1.6  mrg   RND_LOOP (r)
    515      1.1  mrg     {
    516  1.1.1.4  mrg       if (r == MPFR_RNDF)
    517  1.1.1.4  mrg         continue; /* comparison between sub1 and sub1sp makes no sense here */
    518  1.1.1.4  mrg 
    519      1.1  mrg       p = 53;
    520      1.1  mrg       mpfr_set_prec(x, 53);
    521      1.1  mrg       mpfr_set_prec(x2, 53);
    522      1.1  mrg       mpfr_set_prec(y, 53);
    523      1.1  mrg       mpfr_set_prec(z, 53);
    524      1.1  mrg 
    525      1.1  mrg       mpfr_set_str_binary (y,
    526      1.1  mrg        "0.10110111101101110010010010011011000001101101011011001E31");
    527      1.1  mrg 
    528      1.1  mrg       mpfr_sub1sp (x, y, y, (mpfr_rnd_t) r);
    529      1.1  mrg       if (mpfr_cmp_ui(x, 0))
    530      1.1  mrg         {
    531  1.1.1.2  mrg           printf("Error for x-x with p=%lu. Expected 0. Got:",
    532  1.1.1.2  mrg                  (unsigned long) p);
    533  1.1.1.4  mrg           mpfr_dump (x);
    534      1.1  mrg           exit(1);
    535      1.1  mrg         }
    536      1.1  mrg 
    537      1.1  mrg       mpfr_set(z, y, (mpfr_rnd_t) r);
    538      1.1  mrg       mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    539      1.1  mrg       if (mpfr_cmp_ui(x, 0))
    540      1.1  mrg         {
    541  1.1.1.2  mrg           printf("Error for x-y with y=x and p=%lu. Expected 0. Got:",
    542  1.1.1.2  mrg                  (unsigned long) p);
    543  1.1.1.4  mrg           mpfr_dump (x);
    544      1.1  mrg           exit(1);
    545      1.1  mrg         }
    546      1.1  mrg       /* diff = 0 */
    547      1.1  mrg       mpfr_set_str_binary (y,
    548      1.1  mrg        "0.10110111101101110010010010011011001001101101011011001E31");
    549      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    550      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    551      1.1  mrg       if (mpfr_cmp(x, x2))
    552      1.1  mrg         STD_ERROR;
    553      1.1  mrg       if (inexact1 != inexact2)
    554      1.1  mrg         STD_ERROR2;
    555      1.1  mrg 
    556      1.1  mrg       /* Diff = 1 */
    557      1.1  mrg       mpfr_set_str_binary (y,
    558      1.1  mrg        "0.10110111101101110010010010011011000001101101011011001E30");
    559      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    560      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    561      1.1  mrg       if (mpfr_cmp(x, x2))
    562      1.1  mrg         STD_ERROR;
    563      1.1  mrg       if (inexact1 != inexact2)
    564      1.1  mrg         STD_ERROR2;
    565      1.1  mrg 
    566      1.1  mrg       /* Diff = 2 */
    567      1.1  mrg       mpfr_set_str_binary (y,
    568      1.1  mrg        "0.10110111101101110010010010011011000101101101011011001E32");
    569      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    570      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    571      1.1  mrg       if (mpfr_cmp(x, x2))
    572      1.1  mrg         STD_ERROR;
    573      1.1  mrg       if (inexact1 != inexact2)
    574      1.1  mrg         STD_ERROR2;
    575      1.1  mrg 
    576      1.1  mrg       /* Diff = 32 */
    577      1.1  mrg       mpfr_set_str_binary (y,
    578      1.1  mrg        "0.10110111101101110010010010011011000001101101011011001E63");
    579      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    580      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    581      1.1  mrg       if (mpfr_cmp(x, x2))
    582      1.1  mrg         STD_ERROR;
    583      1.1  mrg       if (inexact1 != inexact2)
    584      1.1  mrg         STD_ERROR2;
    585      1.1  mrg 
    586      1.1  mrg       /* Diff = 52 */
    587      1.1  mrg       mpfr_set_str_binary (y,
    588      1.1  mrg        "0.10110111101101110010010010011011010001101101011011001E83");
    589      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    590      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    591      1.1  mrg       if (mpfr_cmp(x, x2))
    592      1.1  mrg         STD_ERROR;
    593      1.1  mrg       if (inexact1 != inexact2)
    594      1.1  mrg         STD_ERROR2;
    595      1.1  mrg 
    596      1.1  mrg       /* Diff = 53 */
    597      1.1  mrg       mpfr_set_str_binary (y,
    598      1.1  mrg        "0.10110111101101110010010010011111000001101101011011001E31");
    599      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    600      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    601      1.1  mrg       if (mpfr_cmp(x, x2))
    602      1.1  mrg         STD_ERROR;
    603      1.1  mrg       if (inexact1 != inexact2)
    604      1.1  mrg         STD_ERROR2;
    605      1.1  mrg 
    606      1.1  mrg       /* Diff > 200 */
    607      1.1  mrg       mpfr_set_str_binary (y,
    608      1.1  mrg        "0.10110111101101110010010010011011000001101101011011001E331");
    609      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    610      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    611      1.1  mrg       if (mpfr_cmp(x, x2))
    612      1.1  mrg         STD_ERROR;
    613      1.1  mrg       if (inexact1 != inexact2)
    614      1.1  mrg         STD_ERROR2;
    615      1.1  mrg 
    616      1.1  mrg       mpfr_set_str_binary (y,
    617      1.1  mrg        "0.10000000000000000000000000000000000000000000000000000E31");
    618      1.1  mrg       mpfr_set_str_binary (z,
    619      1.1  mrg        "0.11111111111111111111111111111111111111111111111111111E30");
    620      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    621      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    622      1.1  mrg       if (mpfr_cmp(x, x2))
    623      1.1  mrg         STD_ERROR;
    624      1.1  mrg       if (inexact1 != inexact2)
    625      1.1  mrg         STD_ERROR2;
    626      1.1  mrg 
    627      1.1  mrg       mpfr_set_str_binary (y,
    628      1.1  mrg        "0.10000000000000000000000000000000000000000000000000000E31");
    629      1.1  mrg       mpfr_set_str_binary (z,
    630      1.1  mrg        "0.11111111111111111111111111111111111111111111111111111E29");
    631      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    632      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    633      1.1  mrg       if (mpfr_cmp(x, x2))
    634      1.1  mrg         STD_ERROR;
    635      1.1  mrg       if (inexact1 != inexact2)
    636      1.1  mrg         STD_ERROR2;
    637      1.1  mrg 
    638      1.1  mrg       mpfr_set_str_binary (y,
    639      1.1  mrg        "0.10000000000000000000000000000000000000000000000000000E52");
    640      1.1  mrg       mpfr_set_str_binary (z,
    641      1.1  mrg        "0.10000000000010000000000000000000000000000000000000000E00");
    642      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    643      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    644      1.1  mrg       if (mpfr_cmp(x, x2))
    645      1.1  mrg         STD_ERROR;
    646      1.1  mrg       if (inexact1 != inexact2)
    647      1.1  mrg         STD_ERROR2;
    648      1.1  mrg 
    649      1.1  mrg       mpfr_set_str_binary (y,
    650      1.1  mrg         "0.11100000000000000000000000000000000000000000000000000E53");
    651      1.1  mrg       mpfr_set_str_binary (z,
    652      1.1  mrg         "0.10000000000000000000000000000000000000000000000000000E00");
    653      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    654      1.1  mrg       inexact2 = mpfr_sub1sp(z, y, z, (mpfr_rnd_t) r);
    655      1.1  mrg       mpfr_set(x, z, (mpfr_rnd_t) r);
    656      1.1  mrg       if (mpfr_cmp(x, x2))
    657      1.1  mrg         STD_ERROR;
    658      1.1  mrg       if (inexact1 != inexact2)
    659      1.1  mrg         STD_ERROR2;
    660      1.1  mrg 
    661      1.1  mrg       mpfr_set_str_binary (y,
    662      1.1  mrg        "0.10000000000000000000000000000000000000000000000000000E53");
    663      1.1  mrg       mpfr_set_str_binary (z,
    664      1.1  mrg        "0.10100000000000000000000000000000000000000000000000000E00");
    665      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    666      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    667      1.1  mrg       if (mpfr_cmp(x, x2))
    668      1.1  mrg         STD_ERROR;
    669      1.1  mrg       if (inexact1 != inexact2)
    670      1.1  mrg         STD_ERROR2;
    671      1.1  mrg 
    672      1.1  mrg       mpfr_set_str_binary (y,
    673      1.1  mrg         "0.10000000000000000000000000000000000000000000000000000E54");
    674      1.1  mrg       mpfr_set_str_binary (z,
    675      1.1  mrg         "0.10100000000000000000000000000000000000000000000000000E00");
    676      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    677      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    678      1.1  mrg       if (mpfr_cmp(x, x2))
    679      1.1  mrg         STD_ERROR;
    680      1.1  mrg       if (inexact1 != inexact2)
    681      1.1  mrg         STD_ERROR2;
    682      1.1  mrg 
    683      1.1  mrg       p = 63;
    684      1.1  mrg       mpfr_set_prec(x, p);
    685      1.1  mrg       mpfr_set_prec(x2, p);
    686      1.1  mrg       mpfr_set_prec(y, p);
    687      1.1  mrg       mpfr_set_prec(z, p);
    688      1.1  mrg       mpfr_set_str_binary (y,
    689      1.1  mrg       "0.100000000000000000000000000000000000000000000000000000000000000E62");
    690      1.1  mrg       mpfr_set_str_binary (z,
    691      1.1  mrg       "0.110000000000000000000000000000000000000000000000000000000000000E00");
    692      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    693      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    694      1.1  mrg       if (mpfr_cmp(x, x2))
    695      1.1  mrg         STD_ERROR;
    696      1.1  mrg       if (inexact1 != inexact2)
    697      1.1  mrg         STD_ERROR2;
    698      1.1  mrg 
    699      1.1  mrg       p = 64;
    700      1.1  mrg       mpfr_set_prec(x, 64);
    701      1.1  mrg       mpfr_set_prec(x2, 64);
    702      1.1  mrg       mpfr_set_prec(y, 64);
    703      1.1  mrg       mpfr_set_prec(z, 64);
    704      1.1  mrg 
    705      1.1  mrg       mpfr_set_str_binary (y,
    706      1.1  mrg       "0.1100000000000000000000000000000000000000000000000000000000000000E31");
    707      1.1  mrg       mpfr_set_str_binary (z,
    708      1.1  mrg       "0.1111111111111111111111111110000000000000000000000000011111111111E29");
    709      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    710      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    711      1.1  mrg       if (mpfr_cmp(x, x2))
    712      1.1  mrg         STD_ERROR;
    713      1.1  mrg       if (inexact1 != inexact2)
    714      1.1  mrg         STD_ERROR2;
    715      1.1  mrg 
    716      1.1  mrg       mpfr_set_str_binary (y,
    717      1.1  mrg       "0.1000000000000000000000000000000000000000000000000000000000000000E63");
    718      1.1  mrg       mpfr_set_str_binary (z,
    719      1.1  mrg       "0.1011000000000000000000000000000000000000000000000000000000000000E00");
    720      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    721      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    722      1.1  mrg       if (mpfr_cmp(x, x2))
    723      1.1  mrg         STD_ERROR;
    724      1.1  mrg       if (inexact1 != inexact2)
    725      1.1  mrg         STD_ERROR2;
    726      1.1  mrg 
    727      1.1  mrg       mpfr_set_str_binary (y,
    728      1.1  mrg       "0.1000000000000000000000000000000000000000000000000000000000000000E63");
    729      1.1  mrg       mpfr_set_str_binary (z,
    730      1.1  mrg       "0.1110000000000000000000000000000000000000000000000000000000000000E00");
    731      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    732      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    733      1.1  mrg       if (mpfr_cmp(x, x2))
    734      1.1  mrg         STD_ERROR;
    735      1.1  mrg       if (inexact1 != inexact2)
    736      1.1  mrg         STD_ERROR2;
    737      1.1  mrg 
    738      1.1  mrg       mpfr_set_str_binary (y,
    739      1.1  mrg         "0.10000000000000000000000000000000000000000000000000000000000000E63");
    740      1.1  mrg       mpfr_set_str_binary (z,
    741      1.1  mrg         "0.10000000000000000000000000000000000000000000000000000000000000E00");
    742      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    743      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    744      1.1  mrg       if (mpfr_cmp(x, x2))
    745      1.1  mrg         STD_ERROR;
    746      1.1  mrg       if (inexact1 != inexact2)
    747      1.1  mrg         STD_ERROR2;
    748      1.1  mrg 
    749      1.1  mrg       mpfr_set_str_binary (y,
    750      1.1  mrg       "0.1000000000000000000000000000000000000000000000000000000000000000E64");
    751      1.1  mrg       mpfr_set_str_binary (z,
    752      1.1  mrg       "0.1010000000000000000000000000000000000000000000000000000000000000E00");
    753      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    754      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    755      1.1  mrg       if (mpfr_cmp(x, x2))
    756      1.1  mrg         STD_ERROR;
    757      1.1  mrg       if (inexact1 != inexact2)
    758      1.1  mrg         STD_ERROR2;
    759      1.1  mrg 
    760      1.1  mrg       MPFR_SET_NAN(x);
    761      1.1  mrg       MPFR_SET_NAN(x2);
    762      1.1  mrg       mpfr_set_str_binary (y,
    763      1.1  mrg       "0.1000000000000000000000000000000000000000000000000000000000000000"
    764      1.1  mrg                           "E-1073741823");
    765      1.1  mrg       mpfr_set_str_binary (z,
    766      1.1  mrg       "0.1100000000000000000000000000000000000000000000000000000000000000"
    767      1.1  mrg                           "E-1073741823");
    768      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    769      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    770      1.1  mrg       if (mpfr_cmp(x, x2))
    771      1.1  mrg         STD_ERROR;
    772      1.1  mrg       if (inexact1 != inexact2)
    773      1.1  mrg         STD_ERROR2;
    774      1.1  mrg 
    775      1.1  mrg       p = 9;
    776      1.1  mrg       mpfr_set_prec(x, p);
    777      1.1  mrg       mpfr_set_prec(x2, p);
    778      1.1  mrg       mpfr_set_prec(y, p);
    779      1.1  mrg       mpfr_set_prec(z, p);
    780      1.1  mrg 
    781      1.1  mrg       mpfr_set_str_binary (y, "0.100000000E1");
    782      1.1  mrg       mpfr_set_str_binary (z, "0.100000000E-8");
    783      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    784      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    785      1.1  mrg       if (mpfr_cmp(x, x2))
    786      1.1  mrg         STD_ERROR;
    787      1.1  mrg       if (inexact1 != inexact2)
    788      1.1  mrg         STD_ERROR2;
    789      1.1  mrg 
    790      1.1  mrg       p = 34;
    791      1.1  mrg       mpfr_set_prec(x, p);
    792      1.1  mrg       mpfr_set_prec(x2, p);
    793      1.1  mrg       mpfr_set_prec(y, p);
    794      1.1  mrg       mpfr_set_prec(z, p);
    795      1.1  mrg 
    796      1.1  mrg       mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18");
    797      1.1  mrg       mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14");
    798      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    799      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    800      1.1  mrg       if (mpfr_cmp(x, x2))
    801      1.1  mrg         STD_ERROR;
    802      1.1  mrg       if (inexact1 != inexact2)
    803      1.1  mrg         STD_ERROR2;
    804      1.1  mrg 
    805      1.1  mrg       p = 124;
    806      1.1  mrg       mpfr_set_prec(x, p);
    807      1.1  mrg       mpfr_set_prec(x2, p);
    808      1.1  mrg       mpfr_set_prec(y, p);
    809      1.1  mrg       mpfr_set_prec(z, p);
    810      1.1  mrg 
    811      1.1  mrg       mpfr_set_str_binary (y,
    812      1.1  mrg "0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
    813      1.1  mrg       mpfr_set_str_binary (z,
    814      1.1  mrg "0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31");
    815      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    816      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    817      1.1  mrg       if (mpfr_cmp(x, x2))
    818      1.1  mrg         STD_ERROR;
    819      1.1  mrg       if (inexact1 != inexact2)
    820      1.1  mrg         STD_ERROR2;
    821      1.1  mrg 
    822      1.1  mrg       p = 288;
    823      1.1  mrg       mpfr_set_prec(x, p);
    824      1.1  mrg       mpfr_set_prec(x2, p);
    825      1.1  mrg       mpfr_set_prec(y, p);
    826      1.1  mrg       mpfr_set_prec(z, p);
    827      1.1  mrg 
    828      1.1  mrg       mpfr_set_str_binary (y,
    829      1.1  mrg      "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
    830      1.1  mrg       mpfr_set_str_binary (z,
    831      1.1  mrg      "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
    832      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    833      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    834      1.1  mrg       if (mpfr_cmp(x, x2))
    835      1.1  mrg         STD_ERROR;
    836      1.1  mrg       if (inexact1 != inexact2)
    837      1.1  mrg         STD_ERROR2;
    838      1.1  mrg 
    839      1.1  mrg       p = 85;
    840      1.1  mrg       mpfr_set_prec(x, p);
    841      1.1  mrg       mpfr_set_prec(x2, p);
    842      1.1  mrg       mpfr_set_prec(y, p);
    843      1.1  mrg       mpfr_set_prec(z, p);
    844      1.1  mrg 
    845      1.1  mrg       mpfr_set_str_binary (y,
    846      1.1  mrg "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
    847      1.1  mrg       mpfr_set_str_binary (z,
    848      1.1  mrg "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
    849      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    850      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    851      1.1  mrg       if (mpfr_cmp(x, x2))
    852      1.1  mrg         STD_ERROR;
    853      1.1  mrg       if (inexact1 != inexact2)
    854      1.1  mrg         STD_ERROR2;
    855      1.1  mrg 
    856      1.1  mrg       p = 64;
    857      1.1  mrg       mpfr_set_prec(x, p); mpfr_set_prec(x2, p);
    858      1.1  mrg       mpfr_set_prec(y, p); mpfr_set_prec(z, p);
    859      1.1  mrg 
    860      1.1  mrg       mpfr_set_str_binary (y,
    861      1.1  mrg                           "0.11000000000000000000000000000000"
    862      1.1  mrg                           "00000000000000000000000000000000E1");
    863      1.1  mrg       mpfr_set_str_binary (z,
    864      1.1  mrg                           "0.10000000000000000000000000000000"
    865      1.1  mrg                           "00000000000000000000000000000001E0");
    866      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    867      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    868      1.1  mrg       if (mpfr_cmp(x, x2))
    869      1.1  mrg         STD_ERROR;
    870      1.1  mrg       if (inexact1 != inexact2)
    871      1.1  mrg         STD_ERROR2;
    872      1.1  mrg 
    873      1.1  mrg       mpfr_set_str_binary (y,
    874      1.1  mrg                           "0.11000000000000000000000000000000"
    875      1.1  mrg                           "000000000000000000000000000001E1");
    876      1.1  mrg       mpfr_set_str_binary (z,
    877      1.1  mrg                           "0.10000000000000000000000000000000"
    878      1.1  mrg                           "00000000000000000000000000000001E0");
    879      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    880      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    881      1.1  mrg       if (mpfr_cmp(x, x2))
    882      1.1  mrg         STD_ERROR;
    883      1.1  mrg       if (inexact1 != inexact2)
    884      1.1  mrg         STD_ERROR2;
    885      1.1  mrg 
    886      1.1  mrg       es = mpfr_get_emin ();
    887      1.1  mrg       set_emin (-1024);
    888      1.1  mrg 
    889      1.1  mrg       mpfr_set_str_binary (y,
    890      1.1  mrg                           "0.10000000000000000000000000000000"
    891      1.1  mrg                           "000000000000000000000000000000E-1023");
    892      1.1  mrg       mpfr_set_str_binary (z,
    893      1.1  mrg                           "0.10000000000000000000000000000000"
    894      1.1  mrg                           "00000000000000000000000000000001E-1023");
    895      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    896      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    897      1.1  mrg       if (mpfr_cmp(x, x2))
    898      1.1  mrg         STD_ERROR;
    899      1.1  mrg       if (inexact1 != inexact2)
    900      1.1  mrg         STD_ERROR2;
    901      1.1  mrg 
    902      1.1  mrg       mpfr_set_str_binary (y,
    903      1.1  mrg                            "0.10000000000000000000000000000000"
    904      1.1  mrg                            "000000000000000000000000000000E-1023");
    905      1.1  mrg       mpfr_set_str_binary (z,
    906      1.1  mrg                            "0.1000000000000000000000000000000"
    907      1.1  mrg                            "000000000000000000000000000000E-1023");
    908      1.1  mrg       inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
    909      1.1  mrg       inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
    910      1.1  mrg       if (mpfr_cmp(x, x2))
    911      1.1  mrg         STD_ERROR;
    912      1.1  mrg       if (inexact1 != inexact2)
    913      1.1  mrg         STD_ERROR2;
    914      1.1  mrg 
    915      1.1  mrg       set_emin (es);
    916      1.1  mrg     }
    917      1.1  mrg 
    918      1.1  mrg   mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
    919      1.1  mrg }
    920  1.1.1.4  mrg 
    921  1.1.1.4  mrg static void
    922  1.1.1.4  mrg check_underflow (mpfr_prec_t p)
    923  1.1.1.4  mrg {
    924  1.1.1.4  mrg   mpfr_t x, y, z;
    925  1.1.1.4  mrg   int inexact;
    926  1.1.1.4  mrg 
    927  1.1.1.4  mrg   mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
    928  1.1.1.4  mrg 
    929  1.1.1.4  mrg   if (p >= 2) /* we need p >= 2 so that 3 is exact */
    930  1.1.1.4  mrg     {
    931  1.1.1.4  mrg       mpfr_set_ui_2exp (y, 4, mpfr_get_emin () - 2, MPFR_RNDN);
    932  1.1.1.4  mrg       mpfr_set_ui_2exp (z, 3, mpfr_get_emin () - 2, MPFR_RNDN);
    933  1.1.1.4  mrg       inexact = mpfr_sub (x, y, z, MPFR_RNDN);
    934  1.1.1.4  mrg       if (inexact >= 0 || (mpfr_cmp_ui (x, 0) != 0))
    935  1.1.1.4  mrg         {
    936  1.1.1.5  mrg           printf ("4*2^(emin-2) - 3*2^(emin-2) with RNDN failed for p=%ld\n",
    937  1.1.1.5  mrg                   (long) p);
    938  1.1.1.4  mrg           printf ("Expected inexact < 0 with x=0\n");
    939  1.1.1.4  mrg           printf ("Got inexact=%d with x=", inexact);
    940  1.1.1.4  mrg           mpfr_dump (x);
    941  1.1.1.4  mrg           exit (1);
    942  1.1.1.4  mrg         }
    943  1.1.1.4  mrg     }
    944  1.1.1.4  mrg 
    945  1.1.1.4  mrg   if (p >= 3) /* we need p >= 3 so that 5 is exact */
    946  1.1.1.4  mrg     {
    947  1.1.1.4  mrg       mpfr_set_ui_2exp (y, 5, mpfr_get_emin () - 2, MPFR_RNDN);
    948  1.1.1.4  mrg       mpfr_set_ui_2exp (z, 4, mpfr_get_emin () - 2, MPFR_RNDN);
    949  1.1.1.4  mrg       inexact = mpfr_sub (x, y, z, MPFR_RNDN);
    950  1.1.1.4  mrg       if (inexact >= 0 || (mpfr_cmp_ui (x, 0) != 0))
    951  1.1.1.4  mrg         {
    952  1.1.1.5  mrg           printf ("5*2^(emin-2) - 4*2^(emin-2) with RNDN failed for p=%ld\n",
    953  1.1.1.5  mrg                   (long) p);
    954  1.1.1.4  mrg           printf ("Expected inexact < 0 with x=0\n");
    955  1.1.1.4  mrg           printf ("Got inexact=%d with x=", inexact);
    956  1.1.1.4  mrg           mpfr_dump (x);
    957  1.1.1.4  mrg           exit (1);
    958  1.1.1.4  mrg         }
    959  1.1.1.4  mrg     }
    960  1.1.1.4  mrg 
    961  1.1.1.4  mrg   mpfr_clears (x, y, z, (mpfr_ptr) 0);
    962  1.1.1.4  mrg }
    963  1.1.1.4  mrg 
    964  1.1.1.4  mrg /* check corner cases of mpfr_sub1sp in case d = 1 and limb = MPFR_LIMB_HIGHBIT */
    965  1.1.1.4  mrg static void
    966  1.1.1.4  mrg check_corner (mpfr_prec_t p)
    967  1.1.1.4  mrg {
    968  1.1.1.4  mrg   mpfr_t x, y, z;
    969  1.1.1.4  mrg   mpfr_exp_t e;
    970  1.1.1.4  mrg   int inex, odd;
    971  1.1.1.4  mrg 
    972  1.1.1.4  mrg   if (p < 4) /* ensures that the initial value of z is > 1 below */
    973  1.1.1.4  mrg     return;
    974  1.1.1.4  mrg 
    975  1.1.1.4  mrg   mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
    976  1.1.1.4  mrg   mpfr_const_pi (y, MPFR_RNDN);
    977  1.1.1.4  mrg   mpfr_set_ui (z, 2, MPFR_RNDN);
    978  1.1.1.4  mrg   inex = mpfr_sub (z, y, z, MPFR_RNDN); /* z is near pi-2, thus y-z is near 2 */
    979  1.1.1.4  mrg   MPFR_ASSERTN(inex == 0);
    980  1.1.1.4  mrg   for (e = 0; e < p; e++)
    981  1.1.1.4  mrg     {
    982  1.1.1.4  mrg       /* add 2^(-e) to z */
    983  1.1.1.5  mrg       mpfr_mul_2ui (z, z, e, MPFR_RNDN);
    984  1.1.1.4  mrg       inex = mpfr_add_ui (z, z, 1, MPFR_RNDN);
    985  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
    986  1.1.1.5  mrg       mpfr_div_2ui (z, z, e, MPFR_RNDN);
    987  1.1.1.4  mrg 
    988  1.1.1.4  mrg       /* compute x = y - z which should be exact, near 2-2^(-e) */
    989  1.1.1.4  mrg       inex = mpfr_sub (x, y, z, MPFR_RNDN);
    990  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
    991  1.1.1.4  mrg       MPFR_ASSERTN(mpfr_get_exp (x) == 1);
    992  1.1.1.4  mrg 
    993  1.1.1.4  mrg       /* restore initial z */
    994  1.1.1.5  mrg       mpfr_mul_2ui (z, z, e, MPFR_RNDN);
    995  1.1.1.4  mrg       inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
    996  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
    997  1.1.1.5  mrg       mpfr_div_2ui (z, z, e, MPFR_RNDN);
    998  1.1.1.4  mrg 
    999  1.1.1.4  mrg       /* subtract 2^(-e) to z */
   1000  1.1.1.5  mrg       mpfr_mul_2ui (z, z, e, MPFR_RNDN);
   1001  1.1.1.4  mrg       inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
   1002  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
   1003  1.1.1.5  mrg       mpfr_div_2ui (z, z, e, MPFR_RNDN);
   1004  1.1.1.4  mrg 
   1005  1.1.1.4  mrg       /* ensure last significant bit of z is 0 so that y-z is exact */
   1006  1.1.1.4  mrg       odd = mpfr_min_prec (z) == p;
   1007  1.1.1.4  mrg       if (odd) /* add one ulp to z */
   1008  1.1.1.4  mrg         mpfr_nextabove (z);
   1009  1.1.1.4  mrg 
   1010  1.1.1.4  mrg       /* compute x = y - z which should be exact, near 2+2^(-e) */
   1011  1.1.1.4  mrg       inex = mpfr_sub (x, y, z, MPFR_RNDN);
   1012  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
   1013  1.1.1.4  mrg       MPFR_ASSERTN(mpfr_get_exp (x) == 2);
   1014  1.1.1.4  mrg 
   1015  1.1.1.4  mrg       /* restore initial z */
   1016  1.1.1.4  mrg       if (odd)
   1017  1.1.1.4  mrg         mpfr_nextbelow (z);
   1018  1.1.1.5  mrg       mpfr_mul_2ui (z, z, e, MPFR_RNDN);
   1019  1.1.1.4  mrg       inex = mpfr_add_ui (z, z, 1, MPFR_RNDN);
   1020  1.1.1.4  mrg       MPFR_ASSERTN(inex == 0);
   1021  1.1.1.5  mrg       mpfr_div_2ui (z, z, e, MPFR_RNDN);
   1022  1.1.1.4  mrg     }
   1023  1.1.1.4  mrg   mpfr_clears (x, y, z, (mpfr_ptr) 0);
   1024  1.1.1.4  mrg }
   1025