Home | History | Annotate | Line # | Download | only in tests
tadd.c revision 1.1.1.3.4.1
      1 /* Test file for mpfr_add and mpfr_sub.
      2 
      3 Copyright 1999-2018 Free Software Foundation, Inc.
      4 Contributed by the AriC and Caramba projects, INRIA.
      5 
      6 This file is part of the GNU MPFR Library.
      7 
      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.
     12 
     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.
     17 
     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. */
     22 
     23 #define N 30000
     24 
     25 #include <float.h>
     26 
     27 #include "mpfr-test.h"
     28 
     29 /* If the precisions are the same, we want to test both mpfr_add1sp
     30    and mpfr_add1. */
     31 
     32 /* FIXME: modify check() to test the ternary value and the flags. */
     33 
     34 static int usesp;
     35 
     36 static int
     37 test_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
     38 {
     39   int res;
     40 #ifdef CHECK_EXTERNAL
     41   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
     42   if (ok)
     43     {
     44       mpfr_print_raw (b);
     45       printf (" ");
     46       mpfr_print_raw (c);
     47     }
     48 #endif
     49   if (usesp || MPFR_ARE_SINGULAR(b,c) || MPFR_SIGN(b) != MPFR_SIGN(c))
     50     res = mpfr_add (a, b, c, rnd_mode);
     51   else
     52     {
     53       if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
     54         res = mpfr_add1(a, c, b, rnd_mode);
     55       else
     56         res = mpfr_add1(a, b, c, rnd_mode);
     57     }
     58 #ifdef CHECK_EXTERNAL
     59   if (ok)
     60     {
     61       printf (" ");
     62       mpfr_print_raw (a);
     63       printf ("\n");
     64     }
     65 #endif
     66   return res;
     67 }
     68 
     69 /* checks that xs+ys gives the expected result zs */
     70 static void
     71 check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode,
     72         unsigned int px, unsigned int py, unsigned int pz, const char *zs)
     73 {
     74   mpfr_t xx,yy,zz;
     75 
     76   mpfr_init2 (xx, px);
     77   mpfr_init2 (yy, py);
     78   mpfr_init2 (zz, pz);
     79 
     80   mpfr_set_str1 (xx, xs);
     81   mpfr_set_str1 (yy, ys);
     82   test_add (zz, xx, yy, rnd_mode);
     83   if (mpfr_cmp_str1 (zz, zs) )
     84     {
     85       printf ("expected sum is %s, got ", zs);
     86       mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN);
     87       printf ("\nmpfr_add failed for x=%s y=%s with rnd_mode=%s\n",
     88               xs, ys, mpfr_print_rnd_mode (rnd_mode));
     89       exit (1);
     90     }
     91   mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
     92 }
     93 
     94 static void
     95 check2b (const char *xs, int px,
     96          const char *ys, int py,
     97          const char *rs, int pz,
     98          mpfr_rnd_t rnd_mode)
     99 {
    100   mpfr_t xx, yy, zz;
    101 
    102   mpfr_init2 (xx,px);
    103   mpfr_init2 (yy,py);
    104   mpfr_init2 (zz,pz);
    105   mpfr_set_str_binary (xx, xs);
    106   mpfr_set_str_binary (yy, ys);
    107   test_add (zz, xx, yy, rnd_mode);
    108   if (mpfr_cmp_str (zz, rs, 2, MPFR_RNDN))
    109     {
    110       printf ("(2) x=%s,%d y=%s,%d pz=%d,rnd=%s\n",
    111               xs, px, ys, py, pz, mpfr_print_rnd_mode (rnd_mode));
    112       printf ("got        "); mpfr_dump (zz);
    113       mpfr_set_str(zz, rs, 2, MPFR_RNDN);
    114       printf ("instead of "); mpfr_dump (zz);
    115       exit (1);
    116     }
    117   mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
    118 }
    119 
    120 static void
    121 check64 (void)
    122 {
    123   mpfr_t x, t, u;
    124 
    125   mpfr_init (x);
    126   mpfr_init (t);
    127   mpfr_init (u);
    128 
    129   mpfr_set_prec (x, 29);
    130   mpfr_set_str_binary (x, "1.1101001000101111011010010110e-3");
    131   mpfr_set_prec (t, 58);
    132   mpfr_set_str_binary (t, "0.11100010011111001001100110010111110110011000000100101E-1");
    133   mpfr_set_prec (u, 29);
    134   test_add (u, x, t, MPFR_RNDD);
    135   mpfr_set_str_binary (t, "1.0101011100001000011100111110e-1");
    136   if (mpfr_cmp (u, t))
    137     {
    138       printf ("mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n");
    139       printf ("expected "); mpfr_out_str (stdout, 2, 29, t, MPFR_RNDN);
    140       puts ("");
    141       printf ("got      "); mpfr_out_str (stdout, 2, 29, u, MPFR_RNDN);
    142       puts ("");
    143       exit(1);
    144     }
    145 
    146   mpfr_set_prec (x, 4);
    147   mpfr_set_str_binary (x, "-1.0E-2");
    148   mpfr_set_prec (t, 2);
    149   mpfr_set_str_binary (t, "-1.1e-2");
    150   mpfr_set_prec (u, 2);
    151   test_add (u, x, t, MPFR_RNDN);
    152   if (MPFR_MANT(u)[0] << 2)
    153     {
    154       printf ("result not normalized for prec=2\n");
    155       mpfr_dump (u);
    156       exit (1);
    157     }
    158   mpfr_set_str_binary (t, "-1.0e-1");
    159   if (mpfr_cmp (u, t))
    160     {
    161       printf ("mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n");
    162       printf ("expected -1.0e-1\n");
    163       printf ("got      "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
    164       puts ("");
    165       exit (1);
    166     }
    167 
    168   mpfr_set_prec (x, 8);
    169   mpfr_set_str_binary (x, "-0.10011010"); /* -77/128 */
    170   mpfr_set_prec (t, 4);
    171   mpfr_set_str_binary (t, "-1.110e-5"); /* -7/128 */
    172   mpfr_set_prec (u, 4);
    173   test_add (u, x, t, MPFR_RNDN); /* should give -5/8 */
    174   mpfr_set_str_binary (t, "-1.010e-1");
    175   if (mpfr_cmp (u, t)) {
    176     printf ("mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n");
    177     printf ("expected -1.010e-1\n");
    178     printf ("got      "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
    179     puts ("");
    180     exit (1);
    181   }
    182 
    183   mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54);
    184   mpfr_set_str_binary (x, "-0.11111100100000000011000011100000101101010001000111E-401");
    185   mpfr_set_str_binary (t, "0.10110000100100000101101100011111111011101000111000101E-464");
    186   test_add (u, x, t, MPFR_RNDN);
    187   if (mpfr_cmp (u, x))
    188     {
    189       printf ("mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n");
    190       exit (1);
    191     }
    192 
    193   mpfr_set_prec (x, 92); mpfr_set_prec (t, 86); mpfr_set_prec (u, 53);
    194   mpfr_set_str (x, "-5.03525136761487735093e-74", 10, MPFR_RNDN);
    195   mpfr_set_str (t, "8.51539046314262304109e-91", 10, MPFR_RNDN);
    196   test_add (u, x, t, MPFR_RNDN);
    197   if (mpfr_cmp_str1 (u, "-5.0352513676148773509283672e-74") )
    198     {
    199       printf ("mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n");
    200       exit (1);
    201     }
    202 
    203   mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76);
    204   mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
    205   mpfr_set_str_binary(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111");
    206   mpfr_sub(u, x, t, MPFR_RNDU);
    207   mpfr_set_str_binary(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100");
    208   if (mpfr_cmp(u,t))
    209     {
    210       printf ("expect "); mpfr_dump (t);
    211       printf ("mpfr_add failed for precisions 53-76\n");
    212       exit (1);
    213     }
    214   mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108);
    215   mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
    216   mpfr_set_str_binary(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111");
    217   mpfr_sub(u, x, t, MPFR_RNDU);
    218   mpfr_set_str_binary(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111");
    219   if (mpfr_cmp(u,t))
    220     {
    221       printf ("expect "); mpfr_dump (t);
    222       printf ("mpfr_add failed for precisions 53-108\n");
    223       exit (1);
    224     }
    225   mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97);
    226   mpfr_set_str_binary(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39");
    227   mpfr_set_ui(t, 1, MPFR_RNDN);
    228   test_add (u, x, t, MPFR_RNDN);
    229   mpfr_set_str_binary(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1");
    230   if (mpfr_cmp(u,x))
    231     {
    232       printf ("mpfr_add failed for precision 97\n");
    233       exit (1);
    234     }
    235   mpfr_set_prec(x, 128); mpfr_set_prec(t, 128); mpfr_set_prec(u, 128);
    236   mpfr_set_str_binary(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4");
    237   mpfr_set(t, x, MPFR_RNDN);
    238   mpfr_sub(u, x, t, MPFR_RNDN);
    239   mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96);
    240   mpfr_set_str_binary(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4");
    241   mpfr_set(t, x, MPFR_RNDN);
    242   mpfr_sub(u, x, t, MPFR_RNDN);
    243   mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85);
    244   mpfr_set_str_binary(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
    245   mpfr_set_str_binary(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
    246   mpfr_sub(u, x, t, MPFR_RNDU);
    247   mpfr_sub(x, x, t, MPFR_RNDU);
    248   if (mpfr_cmp(x, u) != 0)
    249     {
    250       printf ("Error in mpfr_sub: u=x-t and x=x-t give different results\n");
    251       exit (1);
    252     }
    253   if (! MPFR_IS_NORMALIZED (u))
    254     {
    255       printf ("Error in mpfr_sub: result is not msb-normalized (1)\n");
    256       exit (1);
    257     }
    258   mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65);
    259   mpfr_set_str_binary(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
    260   mpfr_set_str_binary(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
    261   mpfr_sub(u, x, t, MPFR_RNDU);
    262   if (mpfr_cmp_ui_2exp(u, 1, 558))
    263     { /* 2^558 */
    264       printf ("Error (1) in mpfr_sub\n");
    265       exit (1);
    266     }
    267 
    268   mpfr_set_prec(x, 64); mpfr_set_prec(t, 64); mpfr_set_prec(u, 64);
    269   mpfr_set_str_binary(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220");
    270   mpfr_set_str_binary(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220");
    271   test_add (u, x, t, MPFR_RNDU);
    272   if ((MPFR_MANT(u)[0] & 1) != 1)
    273     {
    274       printf ("error in mpfr_add with rnd_mode=MPFR_RNDU\n");
    275       printf ("b=  "); mpfr_dump (x);
    276       printf ("c=  "); mpfr_dump (t);
    277       printf ("b+c="); mpfr_dump (u);
    278       exit (1);
    279     }
    280 
    281   /* bug found by Norbert Mueller, 14 Sep 2000 */
    282   mpfr_set_prec(x, 56); mpfr_set_prec(t, 83); mpfr_set_prec(u, 10);
    283   mpfr_set_str_binary(x, "0.10001001011011001111101100110100000101111010010111010111E-7");
    284   mpfr_set_str_binary(t, "0.10001001011011001111101100110100000101111010010111010111000000000111110110110000100E-7");
    285   mpfr_sub(u, x, t, MPFR_RNDU);
    286 
    287   /* array bound write found by Norbert Mueller, 26 Sep 2000 */
    288   mpfr_set_prec(x, 109); mpfr_set_prec(t, 153); mpfr_set_prec(u, 95);
    289   mpfr_set_str_binary(x,"0.1001010000101011101100111000110001111111111111111111111111111111111111111111111111111111111111100000000000000E33");
    290   mpfr_set_str_binary(t,"-0.100101000010101110110011100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100101101000000100100001100110111E33");
    291   test_add (u, x, t, MPFR_RNDN);
    292 
    293   /* array bound writes found by Norbert Mueller, 27 Sep 2000 */
    294   mpfr_set_prec(x, 106); mpfr_set_prec(t, 53); mpfr_set_prec(u, 23);
    295   mpfr_set_str_binary(x, "-0.1000011110101111111001010001000100001011000000000000000000000000000000000000000000000000000000000000000000E-59");
    296   mpfr_set_str_binary(t, "-0.10000111101011111110010100010001101100011100110100000E-59");
    297   mpfr_sub(u, x, t, MPFR_RNDN);
    298   mpfr_set_prec(x, 177); mpfr_set_prec(t, 217); mpfr_set_prec(u, 160);
    299   mpfr_set_str_binary(x, "-0.111010001011010000111001001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E35");
    300   mpfr_set_str_binary(t, "0.1110100010110100001110010010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011010011100001111001E35");
    301   test_add (u, x, t, MPFR_RNDN);
    302   mpfr_set_prec(x, 214); mpfr_set_prec(t, 278); mpfr_set_prec(u, 207);
    303   mpfr_set_str_binary(x, "0.1000100110100110101101101101000000010000100111000001001110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E66");
    304   mpfr_set_str_binary(t, "-0.10001001101001101011011011010000000100001001110000010011100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111011111001001100011E66");
    305   test_add (u, x, t, MPFR_RNDN);
    306   mpfr_set_prec(x, 32); mpfr_set_prec(t, 247); mpfr_set_prec(u, 223);
    307   mpfr_set_str_binary(x, "0.10000000000000000000000000000000E1");
    308   mpfr_set_str_binary(t, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100000100011110000101110110011101110100110110111111011010111100100000000000000000000000000E0");
    309   mpfr_sub(u, x, t, MPFR_RNDN);
    310   if (! MPFR_IS_NORMALIZED (u))
    311     {
    312       printf ("Error in mpfr_sub: result is not msb-normalized (2)\n");
    313       exit (1);
    314     }
    315 
    316   /* bug found by Nathalie Revol, 21 March 2001 */
    317   mpfr_set_prec (x, 65);
    318   mpfr_set_prec (t, 65);
    319   mpfr_set_prec (u, 65);
    320   mpfr_set_str_binary (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
    321   mpfr_set_str_binary (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
    322   mpfr_sub (u, t, x, MPFR_RNDU);
    323   if (! MPFR_IS_NORMALIZED (u))
    324     {
    325       printf ("Error in mpfr_sub: result is not msb-normalized (3)\n");
    326       exit (1);
    327     }
    328 
    329   /* bug found by Fabrice Rouillier, 27 Mar 2001 */
    330   mpfr_set_prec (x, 107);
    331   mpfr_set_prec (t, 107);
    332   mpfr_set_prec (u, 107);
    333   mpfr_set_str_binary (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315");
    334   mpfr_set_str_binary (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350");
    335   mpfr_sub (u, x, t, MPFR_RNDU);
    336   if (! MPFR_IS_NORMALIZED (u))
    337     {
    338       printf ("Error in mpfr_sub: result is not msb-normalized (4)\n");
    339       exit (1);
    340     }
    341 
    342   /* checks that NaN flag is correctly reset */
    343   mpfr_set_ui (t, 1, MPFR_RNDN);
    344   mpfr_set_ui (u, 1, MPFR_RNDN);
    345   mpfr_set_nan (x);
    346   test_add (x, t, u, MPFR_RNDN);
    347   if (mpfr_cmp_ui (x, 2))
    348     {
    349       printf ("Error in mpfr_add: 1+1 gives ");
    350       mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
    351       exit (1);
    352     }
    353 
    354   mpfr_clear(x); mpfr_clear(t); mpfr_clear(u);
    355 }
    356 
    357 /* check case when c does not overlap with a, but both b and c count
    358    for rounding */
    359 static void
    360 check_case_1b (void)
    361 {
    362   mpfr_t a, b, c;
    363   unsigned int prec_a, prec_b, prec_c, dif;
    364 
    365   mpfr_init (a);
    366   mpfr_init (b);
    367   mpfr_init (c);
    368 
    369     {
    370       prec_a = MPFR_PREC_MIN + (randlimb () % 63);
    371       mpfr_set_prec (a, prec_a);
    372       for (prec_b = prec_a + 2; prec_b <= 64; prec_b++)
    373         {
    374           dif = prec_b - prec_a;
    375           mpfr_set_prec (b, prec_b);
    376           /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */
    377           mpfr_set_ui (b, 1, MPFR_RNDN);
    378           mpfr_div_2exp (b, b, dif, MPFR_RNDN);
    379           mpfr_sub_ui (b, b, 1, MPFR_RNDN);
    380           mpfr_div_2exp (b, b, prec_a, MPFR_RNDN);
    381           mpfr_add_ui (b, b, 1, MPFR_RNDN);
    382           for (prec_c = dif; prec_c <= 64; prec_c++)
    383             {
    384               /* c = 2^(-prec_a) - 2^(-prec_b) */
    385               mpfr_set_prec (c, prec_c);
    386               mpfr_set_si (c, -1, MPFR_RNDN);
    387               mpfr_div_2exp (c, c, dif, MPFR_RNDN);
    388               mpfr_add_ui (c, c, 1, MPFR_RNDN);
    389               mpfr_div_2exp (c, c, prec_a, MPFR_RNDN);
    390               test_add (a, b, c, MPFR_RNDN);
    391               if (mpfr_cmp_ui (a, 1) != 0)
    392                 {
    393                   printf ("case (1b) failed for prec_a=%u, prec_b=%u,"
    394                           " prec_c=%u\n", prec_a, prec_b, prec_c);
    395                   printf ("b="); mpfr_dump (b);
    396                   printf ("c="); mpfr_dump (c);
    397                   printf ("a="); mpfr_dump (a);
    398                   exit (1);
    399                 }
    400             }
    401         }
    402     }
    403 
    404   mpfr_clear (a);
    405   mpfr_clear (b);
    406   mpfr_clear (c);
    407 }
    408 
    409 /* check case when c overlaps with a */
    410 static void
    411 check_case_2 (void)
    412 {
    413   mpfr_t a, b, c, d;
    414 
    415   mpfr_init2 (a, 300);
    416   mpfr_init2 (b, 800);
    417   mpfr_init2 (c, 500);
    418   mpfr_init2 (d, 800);
    419 
    420   mpfr_set_str_binary(a, "1E110");  /* a = 2^110 */
    421   mpfr_set_str_binary(b, "1E900");  /* b = 2^900 */
    422   mpfr_set_str_binary(c, "1E500");  /* c = 2^500 */
    423   test_add (c, c, a, MPFR_RNDZ);   /* c = 2^500 + 2^110 */
    424   mpfr_sub (d, b, c, MPFR_RNDZ);   /* d = 2^900 - 2^500 - 2^110 */
    425   test_add (b, b, c, MPFR_RNDZ);   /* b = 2^900 + 2^500 + 2^110 */
    426   test_add (a, b, d, MPFR_RNDZ);   /* a = 2^901 */
    427   if (mpfr_cmp_ui_2exp (a, 1, 901))
    428     {
    429       printf ("b + d fails for b=2^900+2^500+2^110, d=2^900-2^500-2^110\n");
    430       printf ("expected 1.0e901, got ");
    431       mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
    432       printf ("\n");
    433       exit (1);
    434     }
    435 
    436   mpfr_clear (a);
    437   mpfr_clear (b);
    438   mpfr_clear (c);
    439   mpfr_clear (d);
    440 }
    441 
    442 /* checks when source and destination are equal */
    443 static void
    444 check_same (void)
    445 {
    446   mpfr_t x;
    447 
    448   mpfr_init(x); mpfr_set_ui(x, 1, MPFR_RNDZ);
    449   test_add (x, x, x, MPFR_RNDZ);
    450   if (mpfr_cmp_ui (x, 2))
    451     {
    452       printf ("Error when all 3 operands are equal\n");
    453       exit (1);
    454     }
    455   mpfr_clear(x);
    456 }
    457 
    458 #define check53(x, y, r, z) check(x, y, r, 53, 53, 53, z)
    459 
    460 #define MAX_PREC 256
    461 
    462 static void
    463 check_inexact (void)
    464 {
    465   mpfr_t x, y, z, u;
    466   mpfr_prec_t px, py, pu, pz;
    467   int inexact, cmp;
    468   mpfr_rnd_t rnd;
    469 
    470   mpfr_init (x);
    471   mpfr_init (y);
    472   mpfr_init (z);
    473   mpfr_init (u);
    474 
    475   mpfr_set_prec (x, 2);
    476   mpfr_set_str_binary (x, "0.1E-4");
    477   mpfr_set_prec (u, 33);
    478   mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
    479   mpfr_set_prec (y, 31);
    480   inexact = test_add (y, x, u, MPFR_RNDN);
    481 
    482   if (inexact != 0)
    483     {
    484       printf ("Wrong ternary value (2): expected 0, got %d\n", inexact);
    485       exit (1);
    486     }
    487 
    488   mpfr_set_prec (x, 2);
    489   mpfr_set_str_binary (x, "0.1E-4");
    490   mpfr_set_prec (u, 33);
    491   mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
    492   mpfr_set_prec (y, 28);
    493   inexact = test_add (y, x, u, MPFR_RNDN);
    494 
    495   if (inexact != 0)
    496     {
    497       printf ("Wrong ternary value (1): expected 0, got %d\n", inexact);
    498       exit (1);
    499     }
    500 
    501   for (px = 2; px < MAX_PREC; px++)
    502     {
    503       mpfr_set_prec (x, px);
    504 
    505       do
    506         {
    507           mpfr_urandomb (x, RANDS);
    508         }
    509       while (mpfr_cmp_ui (x, 0) == 0);
    510 
    511       for (pu = 2; pu < MAX_PREC; pu++)
    512         {
    513           mpfr_set_prec (u, pu);
    514 
    515           do
    516             {
    517               mpfr_urandomb (u, RANDS);
    518             }
    519           while (mpfr_cmp_ui (u, 0) == 0);
    520 
    521           py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - 1));
    522           mpfr_set_prec (y, py);
    523           pz = mpfr_cmpabs (x, u) >= 0 ?
    524             MPFR_EXP(x) - MPFR_EXP(u) :
    525             MPFR_EXP(u) - MPFR_EXP(x);
    526           /* x + u is exactly representable with precision
    527              abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */
    528           pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1;
    529           mpfr_set_prec (z, pz);
    530 
    531           rnd = RND_RAND_NO_RNDF ();
    532           inexact = test_add (z, x, u, rnd);
    533           if (inexact != 0)
    534             {
    535               printf ("z <- x + u should be exact\n");
    536               printf ("x="); mpfr_dump (x);
    537               printf ("u="); mpfr_dump (u);
    538               printf ("z="); mpfr_dump (z);
    539               exit (1);
    540             }
    541 
    542           rnd = RND_RAND_NO_RNDF ();
    543           inexact = test_add (y, x, u, rnd);
    544           cmp = mpfr_cmp (y, z);
    545           if ((inexact == 0 && cmp != 0) ||
    546               (inexact > 0 && cmp <= 0) ||
    547               (inexact < 0 && cmp >= 0))
    548             {
    549               printf ("Wrong ternary value for rnd=%s\n",
    550                       mpfr_print_rnd_mode (rnd));
    551               printf ("expected %d, got %d\n", cmp, inexact);
    552               printf ("x="); mpfr_dump (x);
    553               printf ("u="); mpfr_dump (u);
    554               printf ("y=  "); mpfr_dump (y);
    555               printf ("x+u="); mpfr_dump (z);
    556               exit (1);
    557             }
    558         }
    559     }
    560 
    561   mpfr_clear (x);
    562   mpfr_clear (y);
    563   mpfr_clear (z);
    564   mpfr_clear (u);
    565 }
    566 
    567 static void
    568 check_nans (void)
    569 {
    570   mpfr_t  s, x, y;
    571 
    572   mpfr_init2 (x, 8L);
    573   mpfr_init2 (y, 8L);
    574   mpfr_init2 (s, 8L);
    575 
    576   /* +inf + -inf == nan */
    577   mpfr_set_inf (x, 1);
    578   mpfr_set_inf (y, -1);
    579   test_add (s, x, y, MPFR_RNDN);
    580   MPFR_ASSERTN (mpfr_nan_p (s));
    581 
    582   /* +inf + 1 == +inf */
    583   mpfr_set_inf (x, 1);
    584   mpfr_set_ui (y, 1L, MPFR_RNDN);
    585   test_add (s, x, y, MPFR_RNDN);
    586   MPFR_ASSERTN (mpfr_inf_p (s));
    587   MPFR_ASSERTN (mpfr_sgn (s) > 0);
    588 
    589   /* -inf + 1 == -inf */
    590   mpfr_set_inf (x, -1);
    591   mpfr_set_ui (y, 1L, MPFR_RNDN);
    592   test_add (s, x, y, MPFR_RNDN);
    593   MPFR_ASSERTN (mpfr_inf_p (s));
    594   MPFR_ASSERTN (mpfr_sgn (s) < 0);
    595 
    596   /* 1 + +inf == +inf */
    597   mpfr_set_ui (x, 1L, MPFR_RNDN);
    598   mpfr_set_inf (y, 1);
    599   test_add (s, x, y, MPFR_RNDN);
    600   MPFR_ASSERTN (mpfr_inf_p (s));
    601   MPFR_ASSERTN (mpfr_sgn (s) > 0);
    602 
    603   /* 1 + -inf == -inf */
    604   mpfr_set_ui (x, 1L, MPFR_RNDN);
    605   mpfr_set_inf (y, -1);
    606   test_add (s, x, y, MPFR_RNDN);
    607   MPFR_ASSERTN (mpfr_inf_p (s));
    608   MPFR_ASSERTN (mpfr_sgn (s) < 0);
    609 
    610   mpfr_clear (x);
    611   mpfr_clear (y);
    612   mpfr_clear (s);
    613 }
    614 
    615 static void
    616 check_alloc (void)
    617 {
    618   mpfr_t a;
    619 
    620   mpfr_init2 (a, 10000);
    621   mpfr_set_prec (a, 53);
    622   mpfr_set_ui (a, 15236, MPFR_RNDN);
    623   test_add (a, a, a, MPFR_RNDN);
    624   mpfr_mul (a, a, a, MPFR_RNDN);
    625   mpfr_div (a, a, a, MPFR_RNDN);
    626   mpfr_sub (a, a, a, MPFR_RNDN);
    627   mpfr_clear (a);
    628 }
    629 
    630 static void
    631 check_overflow (void)
    632 {
    633   mpfr_t a, b, c;
    634   mpfr_prec_t prec_a, prec_b, prec_c;
    635   int r, up;
    636 
    637   mpfr_init (a);
    638   mpfr_init (b);
    639   mpfr_init (c);
    640 
    641   RND_LOOP_NO_RNDF (r)
    642     for (prec_a = 2; prec_a <= 128; prec_a += 2)
    643       for (prec_b = 2; prec_b <= 128; prec_b += 2)
    644         for (prec_c = 2; prec_c <= 128; prec_c += 2)
    645           {
    646             mpfr_set_prec (a, prec_a);
    647             mpfr_set_prec (b, prec_b);
    648             mpfr_set_prec (c, prec_c);
    649 
    650             mpfr_setmax (b, mpfr_get_emax ());
    651 
    652             up = r == MPFR_RNDA || r == MPFR_RNDU || r == MPFR_RNDN;
    653 
    654             /* set c with overlap with bits of b: will always overflow */
    655             mpfr_set_ui_2exp (c, 1, mpfr_get_emax () - prec_b / 2, MPFR_RNDN);
    656             mpfr_nextbelow (c);
    657             mpfr_clear_overflow ();
    658             test_add (a, b, c, (mpfr_rnd_t) r);
    659             if (!mpfr_overflow_p () || (up && !mpfr_inf_p (a)))
    660               {
    661                 printf ("No overflow (1) in check_overflow for rnd=%s\n",
    662                         mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    663                 printf ("b="); mpfr_dump (b);
    664                 printf ("c="); mpfr_dump (c);
    665                 printf ("a="); mpfr_dump (a);
    666                 exit (1);
    667               }
    668 
    669             if (r == MPFR_RNDZ || r == MPFR_RNDD || prec_a >= prec_b + prec_c)
    670               continue;
    671 
    672             /* set c to 111...111 so that ufp(c) = 1/2 ulp(b): will only overflow
    673                when prec_a < prec_b + prec_c, and rounding up or to nearest */
    674             mpfr_set_ui_2exp (c, 1, mpfr_get_emax () - prec_b, MPFR_RNDN);
    675             mpfr_nextbelow (c);
    676             mpfr_clear_overflow ();
    677             test_add (a, b, c, (mpfr_rnd_t) r);
    678             /* b + c is exactly representable iff prec_a >= prec_b + prec_c */
    679             if (!mpfr_overflow_p () || !mpfr_inf_p (a))
    680               {
    681                 printf ("No overflow (2) in check_overflow for rnd=%s\n",
    682                         mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    683                 printf ("b="); mpfr_dump (b);
    684                 printf ("c="); mpfr_dump (c);
    685                 printf ("a="); mpfr_dump (a);
    686                 exit (1);
    687               }
    688           }
    689 
    690   mpfr_set_prec (b, 256);
    691   mpfr_setmax (b, mpfr_get_emax ());
    692   mpfr_set_prec (c, 256);
    693   mpfr_set_ui (c, 1, MPFR_RNDN);
    694   mpfr_set_exp (c, mpfr_get_emax () - 512);
    695   mpfr_set_prec (a, 256);
    696   mpfr_clear_overflow ();
    697   mpfr_add (a, b, c, MPFR_RNDU);
    698   if (!mpfr_overflow_p ())
    699     {
    700       printf ("No overflow (3) in check_overflow\n");
    701       printf ("b="); mpfr_dump (b);
    702       printf ("c="); mpfr_dump (c);
    703       printf ("a="); mpfr_dump (a);
    704       exit (1);
    705     }
    706 
    707   mpfr_clear (a);
    708   mpfr_clear (b);
    709   mpfr_clear (c);
    710 }
    711 
    712 static void
    713 check_1111 (void)
    714 {
    715   mpfr_t one;
    716   long n;
    717 
    718   mpfr_init2 (one, MPFR_PREC_MIN);
    719   mpfr_set_ui (one, 1, MPFR_RNDN);
    720   for (n = 0; n < N; n++)
    721     {
    722       mpfr_prec_t prec_a, prec_b, prec_c;
    723       mpfr_exp_t tb=0, tc, diff;
    724       mpfr_t a, b, c, s;
    725       int m = 512;
    726       int sb, sc;
    727       int inex_a, inex_s;
    728       mpfr_rnd_t rnd_mode;
    729 
    730       prec_a = MPFR_PREC_MIN + (randlimb () % m);
    731       prec_b = MPFR_PREC_MIN + (randlimb () % m);
    732       /* we need prec_c > 1 so that % (prec_c - 1) is well defined below */
    733       do prec_c = MPFR_PREC_MIN + (randlimb () % m); while (prec_c == 1);
    734       mpfr_init2 (a, prec_a);
    735       mpfr_init2 (b, prec_b);
    736       mpfr_init2 (c, prec_c);
    737       /* we need prec_b - (sb != 2) > 0 below */
    738       do sb = randlimb () % 3; while (prec_b - (sb != 2) == 0);
    739       if (sb != 0)
    740         {
    741           tb = 1 + (randlimb () % (prec_b - (sb != 2)));
    742           mpfr_div_2ui (b, one, tb, MPFR_RNDN);
    743           if (sb == 2)
    744             mpfr_neg (b, b, MPFR_RNDN);
    745           test_add (b, b, one, MPFR_RNDN);
    746         }
    747       else
    748         mpfr_set (b, one, MPFR_RNDN);
    749       tc = 1 + (randlimb () % (prec_c - 1));
    750       mpfr_div_2ui (c, one, tc, MPFR_RNDN);
    751       sc = randlimb () % 2;
    752       if (sc)
    753         mpfr_neg (c, c, MPFR_RNDN);
    754       test_add (c, c, one, MPFR_RNDN);
    755       diff = (randlimb () % (2*m)) - m;
    756       mpfr_mul_2si (c, c, diff, MPFR_RNDN);
    757       rnd_mode = RND_RAND_NO_RNDF ();
    758       inex_a = test_add (a, b, c, rnd_mode);
    759       mpfr_init2 (s, MPFR_PREC_MIN + 2*m);
    760       inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
    761       if (inex_s)
    762         {
    763           printf ("check_1111: result should have been exact.\n");
    764           exit (1);
    765         }
    766       inex_s = mpfr_prec_round (s, prec_a, rnd_mode);
    767       if ((inex_a < 0 && inex_s >= 0) ||
    768           (inex_a == 0 && inex_s != 0) ||
    769           (inex_a > 0 && inex_s <= 0) ||
    770           !mpfr_equal_p (a, s))
    771         {
    772           printf ("check_1111: results are different.\n");
    773           printf ("prec_a = %d, prec_b = %d, prec_c = %d\n",
    774                   (int) prec_a, (int) prec_b, (int) prec_c);
    775           printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n",
    776                   (int) tb, (int) tc, (int) diff,
    777                   mpfr_print_rnd_mode (rnd_mode));
    778           printf ("sb = %d, sc = %d\n", sb, sc);
    779           printf ("a = "); mpfr_dump (a);
    780           printf ("s = "); mpfr_dump (s);
    781           printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s);
    782           exit (1);
    783         }
    784       mpfr_clear (a);
    785       mpfr_clear (b);
    786       mpfr_clear (c);
    787       mpfr_clear (s);
    788     }
    789   mpfr_clear (one);
    790 }
    791 
    792 static void
    793 check_1minuseps (void)
    794 {
    795   static mpfr_prec_t prec_a[] = {
    796     MPFR_PREC_MIN, 30, 31, 32, 33, 62, 63, 64, 65, 126, 127, 128, 129
    797   };
    798   static int supp_b[] = {
    799     0, 1, 2, 3, 4, 29, 30, 31, 32, 33, 34, 35, 61, 62, 63, 64, 65, 66, 67
    800   };
    801   mpfr_t a, b, c;
    802   unsigned int ia, ib, ic;
    803 
    804   mpfr_init2 (c, MPFR_PREC_MIN);
    805 
    806   for (ia = 0; ia < numberof (prec_a); ia++)
    807     for (ib = 0; ib < numberof (supp_b); ib++)
    808       {
    809         mpfr_prec_t prec_b;
    810         int rnd_mode;
    811 
    812         prec_b = prec_a[ia] + supp_b[ib];
    813 
    814         mpfr_init2 (a, prec_a[ia]);
    815         mpfr_init2 (b, prec_b);
    816 
    817         mpfr_set_ui (c, 1, MPFR_RNDN);
    818         mpfr_div_ui (b, c, prec_a[ia], MPFR_RNDN);
    819         mpfr_sub (b, c, b, MPFR_RNDN);  /* b = 1 - 2^(-prec_a) */
    820 
    821         for (ic = 0; ic < numberof (supp_b); ic++)
    822           for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
    823             {
    824               mpfr_t s;
    825               int inex_a, inex_s;
    826 
    827               if (rnd_mode == MPFR_RNDF)
    828                 continue; /* inex_a, inex_s make no sense */
    829 
    830               mpfr_set_ui (c, 1, MPFR_RNDN);
    831               mpfr_div_ui (c, c, prec_a[ia] + supp_b[ic], MPFR_RNDN);
    832               inex_a = test_add (a, b, c, (mpfr_rnd_t) rnd_mode);
    833               mpfr_init2 (s, 256);
    834               inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
    835               if (inex_s)
    836                 {
    837                   printf ("check_1minuseps: result should have been exact "
    838                           "(ia = %u, ib = %u, ic = %u)\n", ia, ib, ic);
    839                   exit (1);
    840                 }
    841               inex_s = mpfr_prec_round (s, prec_a[ia], (mpfr_rnd_t) rnd_mode);
    842               if ((inex_a < 0 && inex_s >= 0) ||
    843                   (inex_a == 0 && inex_s != 0) ||
    844                   (inex_a > 0 && inex_s <= 0) ||
    845                   !mpfr_equal_p (a, s))
    846                 {
    847                   printf ("check_1minuseps: results are different.\n");
    848                   printf ("ia = %u, ib = %u, ic = %u\n", ia, ib, ic);
    849                   exit (1);
    850                 }
    851               mpfr_clear (s);
    852             }
    853 
    854         mpfr_clear (a);
    855         mpfr_clear (b);
    856       }
    857 
    858   mpfr_clear (c);
    859 }
    860 
    861 /* Test case bk == 0 in add1.c (b has entirely been read and
    862    c hasn't been taken into account). */
    863 static void
    864 coverage_bk_eq_0 (void)
    865 {
    866   mpfr_t a, b, c;
    867   int inex;
    868 
    869   mpfr_init2 (a, GMP_NUMB_BITS);
    870   mpfr_init2 (b, 2 * GMP_NUMB_BITS);
    871   mpfr_init2 (c, GMP_NUMB_BITS);
    872 
    873   mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
    874   mpfr_sub_ui (b, b, 1, MPFR_RNDN);
    875   /* b = 111...111 (in base 2) where the 1's fit 2 whole limbs */
    876 
    877   mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);  /* c = 1/2 */
    878 
    879   inex = mpfr_add (a, b, c, MPFR_RNDU);
    880   mpfr_set_ui_2exp (c, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
    881   if (! mpfr_equal_p (a, c))
    882     {
    883       printf ("Error in coverage_bk_eq_0\n");
    884       printf ("Expected ");
    885       mpfr_dump (c);
    886       printf ("Got      ");
    887       mpfr_dump (a);
    888       exit (1);
    889     }
    890   MPFR_ASSERTN (inex > 0);
    891 
    892   mpfr_clear (a);
    893   mpfr_clear (b);
    894   mpfr_clear (c);
    895 }
    896 
    897 static void
    898 tests (void)
    899 {
    900   check_alloc ();
    901   check_nans ();
    902   check_inexact ();
    903   check_case_1b ();
    904   check_case_2 ();
    905   check64();
    906   coverage_bk_eq_0 ();
    907 
    908   check("293607738.0", "1.9967571564050541e-5", MPFR_RNDU, 64, 53, 53,
    909         "2.9360773800002003e8");
    910   check("880524.0", "-2.0769715792901673e-5", MPFR_RNDN, 64, 53, 53,
    911         "8.8052399997923023e5");
    912   check("1196426492.0", "-1.4218093058435347e-3", MPFR_RNDN, 64, 53, 53,
    913         "1.1964264919985781e9");
    914   check("982013018.0", "-8.941829477291838e-7", MPFR_RNDN, 64, 53, 53,
    915         "9.8201301799999905e8");
    916   check("1092583421.0", "1.0880649218158844e9", MPFR_RNDN, 64, 53, 53,
    917         "2.1806483428158846e9");
    918   check("1.8476886419022969e-6", "961494401.0", MPFR_RNDN, 53, 64, 53,
    919         "9.6149440100000179e8");
    920   check("-2.3222118418069868e5", "1229318102.0", MPFR_RNDN, 53, 64, 53,
    921         "1.2290858808158193e9");
    922   check("-3.0399171300395734e-6", "874924868.0", MPFR_RNDN, 53, 64, 53,
    923         "8.749248679999969e8");
    924   check("9.064246624706179e1", "663787413.0", MPFR_RNDN, 53, 64, 53,
    925         "6.6378750364246619e8");
    926   check("-1.0954322421551264e2", "281806592.0", MPFR_RNDD, 53, 64, 53,
    927         "2.8180648245677572e8");
    928   check("5.9836930386056659e-8", "1016217213.0", MPFR_RNDN, 53, 64, 53,
    929         "1.0162172130000001e9");
    930   check("-1.2772161928500301e-7", "1237734238.0", MPFR_RNDN, 53, 64, 53,
    931         "1.2377342379999998e9");
    932   check("-4.567291988483277e8", "1262857194.0", MPFR_RNDN, 53, 64, 53,
    933         "8.0612799515167236e8");
    934   check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 53, 53,
    935         "2.4380935175292528e8");
    936   check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 64, 53,
    937         "2.4380935175292528e8");
    938   check("-1.716113812768534e-140", "1271212614.0", MPFR_RNDZ, 53, 64, 53,
    939         "1.2712126139999998e9");
    940   check("-1.2927455200185474e-50", "1675676122.0", MPFR_RNDD, 53, 64, 53,
    941         "1.6756761219999998e9");
    942 
    943   check53("1.22191250737771397120e+20", "948002822.0", MPFR_RNDN,
    944           "122191250738719408128.0");
    945   check53("9966027674114492.0", "1780341389094537.0", MPFR_RNDN,
    946           "11746369063209028.0");
    947   check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
    948           MPFR_RNDN, "3.5274425367757071711e272");
    949   check_same();
    950   check53("6.14384195492641560499e-02", "-6.14384195401037683237e-02",
    951           MPFR_RNDU, "9.1603877261370314499e-12");
    952   check53("1.16809465359248765399e+196", "7.92883212101990665259e+196",
    953           MPFR_RNDU, "9.0969267746123943065e196");
    954   check53("3.14553393112021279444e-67", "3.14553401015952024126e-67", MPFR_RNDU,
    955           "6.2910679412797336946e-67");
    956 
    957   check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDN,
    958           "5.4388530464436950905e185");
    959   check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDZ,
    960           "5.4388530464436944867e185");
    961   check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDU,
    962           "5.4388530464436950905e185");
    963   check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDD,
    964           "5.4388530464436944867e185");
    965 
    966   check2b("1.001010101110011000000010100101110010111001010000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e358",187,
    967           "-1.11100111001101100010001111111110101101110001000000000000000000000000000000000000000000e160",87,
    968           "1.001010101110011000000010100101110010111001010000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e358",178,
    969           MPFR_RNDD);
    970   check2b("-1.111100100011100111010101010101001010100100000111001000000000000000000e481",70,
    971           "1.1111000110100011110101111110110010010000000110101000000000000000e481",65,
    972           "-1.001010111111101011010000001100011101100101000000000000000000e472",61,
    973           MPFR_RNDD);
    974   check2b("1.0100010111010000100101000000111110011100011001011010000000000000000000000000000000e516",83,
    975           "-1.1001111000100001011100000001001100110011110010111111000000e541",59,
    976           "-1.1001111000100001011011110111000001001011100000011110100000110001110011010011000000000000000000000000000000000000000000000000e541",125,
    977           MPFR_RNDZ);
    978   check2b("-1.0010111100000100110001011011010000000011000111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",155,
    979           "-1.00111110100011e239",15,
    980           "-1.00101111000001001100101010101110001100110001111010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",159,
    981           MPFR_RNDD);
    982   check2b("-1.110111000011111011000000001001111101101001010100111000000000000000000000000e880",76,
    983           "-1.1010010e-634",8,
    984           "-1.11011100001111101100000000100111110110100101010011100000000000000000000000e880",75,
    985           MPFR_RNDZ);
    986   check2b("1.00100100110110101001010010101111000001011100100101010000000000000000000000000000e-530",81,
    987           "-1.101101111100000111000011001010110011001011101001110100000e-908",58,
    988           "1.00100100110110101001010010101111000001011100100101010e-530",54,
    989           MPFR_RNDN);
    990   check2b("1.0101100010010111101000000001000010010010011000111011000000000000000000000000000000000000000000000000000000000000000000e374",119,
    991           "1.11100101100101e358",15,
    992           "1.01011000100110011000010110100100100100100110001110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e374",150,
    993           MPFR_RNDZ);
    994   check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
    995           "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
    996           "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
    997           MPFR_RNDZ);
    998   check2b("-1.011110000111101011100001100110100011100101000011011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-189",175,
    999           "1.1e631",2,
   1000           "1.011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e631",115,
   1001           MPFR_RNDZ);
   1002   check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
   1003           "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
   1004           "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
   1005           MPFR_RNDU);
   1006   check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
   1007           "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
   1008           "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
   1009           MPFR_RNDD);
   1010   check2b("-1.1001000011101000110000111110010100100101110101111100000000000000000000000000000000000000000000000000000000e-72",107,
   1011           "-1.001100011101100100010101101010101011010010111111010000000000000000000000000000e521",79,
   1012           "-1.00110001110110010001010110101010101101001011111101000000000000000000000000000000000000000000000001e521",99,
   1013           MPFR_RNDD);
   1014   check2b("-1.01010001111000000101010100100100110101011011100001110000000000e498",63,
   1015           "1.010000011010101111000100111100011100010101011110010100000000000e243",64,
   1016           "-1.010100011110000001010101001001001101010110111000011100000000000e498",64,
   1017           MPFR_RNDN);
   1018   check2b("1.00101100010101000011010000011000111111011110010111000000000000000000000000000000000000000000000000000000000e178",108,
   1019           "-1.10101101010101000110011011111001001101111111110000100000000e160",60,
   1020           "1.00101100010100111100100011000011111001000010011101110010000000001111100000000000000000000000000000000000e178",105,
   1021           MPFR_RNDN);
   1022   check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
   1023           "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
   1024           "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
   1025           MPFR_RNDU);
   1026   check2b("-1.100000111100101001100111011100011011000001101001111100000000000000000000000000e843",79,
   1027           "-1.1101101010110000001001000100001100110011000110110111000000000000000000000000000000000000000000e414",95,
   1028           "-1.1000001111001010011001110111000110110000011010100000e843",53,
   1029           MPFR_RNDD);
   1030   check2b("-1.110110010110100010100011000110111001010000010111110000000000e-415",61,
   1031           "-1.0000100101100001111100110011111111110100011101101011000000000000000000e751",71,
   1032           "-1.00001001011000011111001100111111111101000111011010110e751",54,
   1033           MPFR_RNDN);
   1034   check2b("-1.1011011011110001001101010101001000010100010110111101000000000000000000000e258",74,
   1035           "-1.00011100010110110101001011000100100000100010101000010000000000000000000000000000000000000000000000e268",99,
   1036           "-1.0001110011001001000011110001000111010110101011110010011011110100000000000000000000000000000000000000e268",101,
   1037           MPFR_RNDD);
   1038   check2b("-1.1011101010011101011000000100100110101101101110000001000000000e629",62,
   1039           "1.111111100000011100100011100000011101100110111110111000000000000000000000000000000000000000000e525",94,
   1040           "-1.101110101001110101100000010010011010110110111000000011111111111111111111111111111111111111111111111111101e629",106,
   1041           MPFR_RNDD);
   1042   check2b("1.111001000010001100010000001100000110001011110111011000000000000000000000000000000000000e152",88,
   1043           "1.111110111001100100000100111111010111000100111111001000000000000000e152",67,
   1044           "1.1110111111011110000010101001011011101010000110110100e153",53,
   1045           MPFR_RNDN);
   1046   check2b("1.000001100011110010110000110100001010101101111011110100e696",55,
   1047           "-1.1011001111011100100001011110100101010101110111010101000000000000000000000000000000000000000000000000000000000000e730",113,
   1048           "-1.1011001111011100100001011110100100010100010011100010e730",53,
   1049           MPFR_RNDN);
   1050   check2b("-1.11010111100001001111000001110101010010001111111001100000000000000000000000000000000000000000000000000000000000e530",111,
   1051           "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000e530",99,
   1052           "-1.1000110011110011101010101101111101010011011111000000000000000e528",62,
   1053           MPFR_RNDD);
   1054   check2b("-1.0001100010010100111101101011101000100100010011100011000000000000000000000000000000000000000000000000000000000e733",110,
   1055           "-1.001000000111110010100101010100110111001111011011001000000000000000000000000000000000000000000000000000000000e710",109,
   1056           "-1.000110001001010011111000111110110001110110011000110110e733",55,
   1057           MPFR_RNDN);
   1058   check2b("-1.1101011110000100111100000111010101001000111111100110000000000000000000000e530",74,
   1059           "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000000000000000e530",111,
   1060           "-1.10001100111100111010101011011111010100110111110000000000000000000000000000e528",75,
   1061           MPFR_RNDU);
   1062   check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
   1063           "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
   1064           "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
   1065           MPFR_RNDU);
   1066   check2b("-1.100101111110110000000110111111011010011101101111100100000000000000e-624",67,
   1067           "1.10111010101110100000010110101000000000010011100000100000000e-587",60,
   1068           "1.1011101010111010000001011010011111110100011110001011111111001000000100101100010010000011100000000000000000000e-587",110,
   1069           MPFR_RNDU);
   1070   check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
   1071           "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
   1072           "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
   1073           MPFR_RNDZ);
   1074   check2b("1.1000111000110010101001010011010011101100010110001001000000000000000000000000000000000000000000000000e167",101,
   1075           "1.0011110010000110000000101100100111000001110110110000000000000000000000000e167",74,
   1076           "1.01100101010111000101001111111111010101110001100111001000000000000000000000000000000000000000000000000000e168",105,
   1077           MPFR_RNDZ);
   1078   check2b("1.100101111111110010100101110111100001110000100001010000000000000000000000000000000000000000000000e808",97,
   1079           "-1.1110011001100000100000111111110000110010100111001011000000000000000000000000000000e807",83,
   1080           "1.01001001100110001100011111000000000001011010010111010000000000000000000000000000000000000000000e807",96,
   1081           MPFR_RNDN);
   1082   check2b("1e128",128,
   1083           "1e0",128,
   1084           "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e0",256,
   1085           MPFR_RNDN);
   1086 
   1087   /* Checking double precision (53 bits) */
   1088   check53("-8.22183238641455905806e-19", "7.42227178769761587878e-19",MPFR_RNDD,
   1089           "-7.9956059871694317927e-20");
   1090   check53("5.82106394662028628236e+234","-5.21514064202368477230e+89",MPFR_RNDD,
   1091           "5.8210639466202855763e234");
   1092   check53("5.72931679569871602371e+122","-5.72886070363264321230e+122",
   1093           MPFR_RNDN, "4.5609206607281141508e118");
   1094   check53("-5.09937369394650450820e+238", "2.70203299854862982387e+250",
   1095           MPFR_RNDD, "2.7020329985435301323e250");
   1096   check53("-2.96695924472363684394e+27", "1.22842938251111500000e+16",MPFR_RNDD,
   1097           "-2.96695924471135255027e27");
   1098   check53("1.74693641655743793422e-227", "-7.71776956366861843469e-229",
   1099           MPFR_RNDN, "1.669758720920751867e-227");
   1100   /*  x = -7883040437021647.0; for (i=0; i<468; i++) x = x / 2.0;*/
   1101   check53("-1.03432206392780011159e-125", "1.30127034799251347548e-133",
   1102           MPFR_RNDN,
   1103           "-1.0343220509150965661100887242027378881805094180354e-125");
   1104   check53("1.05824655795525779205e+71", "-1.06022698059744327881e+71",MPFR_RNDZ,
   1105           "-1.9804226421854867632e68");
   1106   check53("-5.84204911040921732219e+240", "7.26658169050749590763e+240",
   1107           MPFR_RNDD, "1.4245325800982785854e240");
   1108   check53("1.00944884131046636376e+221","2.33809162651471520268e+215",MPFR_RNDN,
   1109           "1.0094511794020929787e221");
   1110   /*x = 7045852550057985.0; for (i=0; i<986; i++) x = x / 2.0;*/
   1111   check53("4.29232078932667367325e-278",
   1112           "1.0773525047389793833221116707010783793203080117586e-281"
   1113           , MPFR_RNDU, "4.2933981418314132787e-278");
   1114   check53("5.27584773801377058681e-80", "8.91207657803547196421e-91", MPFR_RNDN,
   1115           "5.2758477381028917269e-80");
   1116   check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
   1117           MPFR_RNDN, "3.5274425367757071711e272");
   1118   check53("4.67302514390488041733e-184", "2.18321376145645689945e-190",
   1119           MPFR_RNDN, "4.6730273271186420541e-184");
   1120   check53("5.57294120336300389254e+71", "2.60596167942024924040e+65", MPFR_RNDZ,
   1121           "5.5729438093246831053e71");
   1122   check53("6.6052588496951015469e24", "4938448004894539.0", MPFR_RNDU,
   1123           "6.6052588546335505068e24");
   1124   check53("1.23056185051606761523e-190", "1.64589756643433857138e-181",
   1125           MPFR_RNDU, "1.6458975676649006598e-181");
   1126   check53("2.93231171510175981584e-280", "3.26266919161341483877e-273",
   1127           MPFR_RNDU, "3.2626694848445867288e-273");
   1128   check53("5.76707395945001907217e-58", "4.74752971449827687074e-51", MPFR_RNDD,
   1129           "4.747530291205672325e-51");
   1130   check53("277363943109.0", "11.0", MPFR_RNDN, "277363943120.0");
   1131   check53("1.44791789689198883921e-140", "-1.90982880222349071284e-121",
   1132           MPFR_RNDN, "-1.90982880222349071e-121");
   1133 
   1134 
   1135   /* tests for particular cases (Vincent Lefevre, 22 Aug 2001) */
   1136   check53("9007199254740992.0", "1.0", MPFR_RNDN, "9007199254740992.0");
   1137   check53("9007199254740994.0", "1.0", MPFR_RNDN, "9007199254740996.0");
   1138   check53("9007199254740992.0", "-1.0", MPFR_RNDN, "9007199254740991.0");
   1139   check53("9007199254740994.0", "-1.0", MPFR_RNDN, "9007199254740992.0");
   1140   check53("9007199254740996.0", "-1.0", MPFR_RNDN, "9007199254740996.0");
   1141 
   1142   check_overflow ();
   1143   check_1111 ();
   1144   check_1minuseps ();
   1145 }
   1146 
   1147 static void
   1148 check_extreme (void)
   1149 {
   1150   mpfr_t u, v, w, x, y;
   1151   int i, inex, r;
   1152 
   1153   mpfr_inits2 (32, u, v, w, x, y, (mpfr_ptr) 0);
   1154   mpfr_setmin (u, mpfr_get_emax ());
   1155   mpfr_setmax (v, mpfr_get_emin ());
   1156   mpfr_setmin (w, mpfr_get_emax () - 40);
   1157   RND_LOOP (r)
   1158     for (i = 0; i < 2; i++)
   1159       {
   1160         mpfr_add (x, u, v, (mpfr_rnd_t) r);
   1161         mpfr_set_prec (y, 64);
   1162         inex = mpfr_add (y, u, w, MPFR_RNDN);
   1163         MPFR_ASSERTN (inex == 0);
   1164         mpfr_prec_round (y, 32, (mpfr_rnd_t) r);
   1165         /* for RNDF, the rounding directions are not necessarily consistent */
   1166         if (! mpfr_equal_p (x, y) && r != MPFR_RNDF)
   1167           {
   1168             printf ("Error in u + v (%s)\n",
   1169                     mpfr_print_rnd_mode ((mpfr_rnd_t) r));
   1170             printf ("u = ");
   1171             mpfr_dump (u);
   1172             printf ("v = ");
   1173             mpfr_dump (v);
   1174             printf ("Expected ");
   1175             mpfr_dump (y);
   1176             printf ("Got      ");
   1177             mpfr_dump (x);
   1178             exit (1);
   1179           }
   1180         mpfr_neg (v, v, MPFR_RNDN);
   1181         mpfr_neg (w, w, MPFR_RNDN);
   1182       }
   1183   mpfr_clears (u, v, w, x, y, (mpfr_ptr) 0);
   1184 }
   1185 
   1186 static void
   1187 testall_rndf (mpfr_prec_t pmax)
   1188 {
   1189   mpfr_t a, b, c, d;
   1190   mpfr_prec_t pa, pb, pc;
   1191   mpfr_exp_t eb;
   1192 
   1193   for (pa = MPFR_PREC_MIN; pa <= pmax; pa++)
   1194     {
   1195       mpfr_init2 (a, pa);
   1196       mpfr_init2 (d, pa);
   1197       for (pb = MPFR_PREC_MIN; pb <= pmax; pb++)
   1198         {
   1199           mpfr_init2 (b, pb);
   1200           for (eb = 0; eb <= pmax + 3; eb ++)
   1201             {
   1202               mpfr_set_ui_2exp (b, 1, eb, MPFR_RNDN);
   1203               while (mpfr_cmp_ui_2exp (b, 1, eb + 1) < 0)
   1204                 {
   1205                   for (pc = MPFR_PREC_MIN; pc <= pmax; pc++)
   1206                     {
   1207                       mpfr_init2 (c, pc);
   1208                       mpfr_set_ui (c, 1, MPFR_RNDN);
   1209                       while (mpfr_cmp_ui (c, 2) < 0)
   1210                         {
   1211                           mpfr_add (a, b, c, MPFR_RNDF);
   1212                           mpfr_add (d, b, c, MPFR_RNDD);
   1213                           if (!mpfr_equal_p (a, d))
   1214                             {
   1215                               mpfr_add (d, b, c, MPFR_RNDU);
   1216                               if (!mpfr_equal_p (a, d))
   1217                                 {
   1218                                   printf ("Error: mpfr_add(a,b,c,RNDF) does not "
   1219                                           "match RNDD/RNDU\n");
   1220                                   printf ("b="); mpfr_dump (b);
   1221                                   printf ("c="); mpfr_dump (c);
   1222                                   printf ("a="); mpfr_dump (a);
   1223                                   exit (1);
   1224                                 }
   1225                             }
   1226                           mpfr_nextabove (c);
   1227                         }
   1228                       mpfr_clear (c);
   1229                     }
   1230                   mpfr_nextabove (b);
   1231                 }
   1232             }
   1233           mpfr_clear (b);
   1234         }
   1235       mpfr_clear (a);
   1236       mpfr_clear (d);
   1237     }
   1238 }
   1239 
   1240 static void
   1241 test_rndf_exact (mp_size_t pmax)
   1242 {
   1243   mpfr_t a, b, c, d;
   1244   mpfr_prec_t pa, pb, pc;
   1245   mpfr_exp_t eb;
   1246 
   1247   for (pa = MPFR_PREC_MIN; pa <= pmax; pa++)
   1248     {
   1249       /* only check pa mod GMP_NUMB_BITS = -2, -1, 0, 1, 2 */
   1250       if ((pa + 2) % GMP_NUMB_BITS > 4)
   1251         continue;
   1252       mpfr_init2 (a, pa);
   1253       mpfr_init2 (d, pa);
   1254       for (pb = MPFR_PREC_MIN; pb <= pmax; pb++)
   1255         {
   1256           if ((pb + 2) % GMP_NUMB_BITS > 4)
   1257             continue;
   1258           mpfr_init2 (b, pb);
   1259           for (eb = 0; eb <= pmax + 3; eb ++)
   1260             {
   1261               mpfr_urandomb (b, RANDS);
   1262               mpfr_mul_2exp (b, b, eb, MPFR_RNDN);
   1263               for (pc = MPFR_PREC_MIN; pc <= pmax; pc++)
   1264                 {
   1265                   if ((pc + 2) % GMP_NUMB_BITS > 4)
   1266                     continue;
   1267                   mpfr_init2 (c, pc);
   1268                   mpfr_urandomb (c, RANDS);
   1269                   mpfr_add (a, b, c, MPFR_RNDF);
   1270                   mpfr_add (d, b, c, MPFR_RNDD);
   1271                   if (!mpfr_equal_p (a, d))
   1272                     {
   1273                       mpfr_add (d, b, c, MPFR_RNDU);
   1274                       if (!mpfr_equal_p (a, d))
   1275                         {
   1276                           printf ("Error: mpfr_add(a,b,c,RNDF) does not "
   1277                                   "match RNDD/RNDU\n");
   1278                           printf ("b="); mpfr_dump (b);
   1279                           printf ("c="); mpfr_dump (c);
   1280                           printf ("a="); mpfr_dump (a);
   1281                           exit (1);
   1282                         }
   1283                     }
   1284 
   1285                   /* now make the low bits from c match those from b */
   1286                   mpfr_sub (c, b, d, MPFR_RNDN);
   1287                   mpfr_add (a, b, c, MPFR_RNDF);
   1288                   mpfr_add (d, b, c, MPFR_RNDD);
   1289                   if (!mpfr_equal_p (a, d))
   1290                     {
   1291                       mpfr_add (d, b, c, MPFR_RNDU);
   1292                       if (!mpfr_equal_p (a, d))
   1293                         {
   1294                           printf ("Error: mpfr_add(a,b,c,RNDF) does not "
   1295                                   "match RNDD/RNDU\n");
   1296                           printf ("b="); mpfr_dump (b);
   1297                           printf ("c="); mpfr_dump (c);
   1298                           printf ("a="); mpfr_dump (a);
   1299                           exit (1);
   1300                         }
   1301                     }
   1302 
   1303                   mpfr_clear (c);
   1304                 }
   1305             }
   1306           mpfr_clear (b);
   1307         }
   1308       mpfr_clear (a);
   1309       mpfr_clear (d);
   1310     }
   1311 }
   1312 
   1313 #define TEST_FUNCTION test_add
   1314 #define TWO_ARGS
   1315 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
   1316 #include "tgeneric.c"
   1317 
   1318 int
   1319 main (int argc, char *argv[])
   1320 {
   1321   tests_start_mpfr ();
   1322 
   1323   usesp = 0;
   1324   tests ();
   1325 
   1326 #ifndef CHECK_EXTERNAL /* no need to check twice */
   1327   usesp = 1;
   1328   tests ();
   1329 #endif
   1330 
   1331   test_rndf_exact (200);
   1332   testall_rndf (7);
   1333   check_extreme ();
   1334 
   1335   test_generic (MPFR_PREC_MIN, 1000, 100);
   1336 
   1337   tests_end_mpfr ();
   1338   return 0;
   1339 }
   1340