Home | History | Annotate | Line # | Download | only in tests
tdiv.c revision 1.1
      1 /* Test file for mpfr_div.
      2 
      3 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4 Contributed by the Arenaire and Cacao 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 #include <stdio.h>
     24 #include <stdlib.h>
     25 
     26 #include "mpfr-test.h"
     27 
     28 #ifdef CHECK_EXTERNAL
     29 static int
     30 test_div (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
     31 {
     32   int res;
     33   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
     34   if (ok)
     35     {
     36       mpfr_print_raw (b);
     37       printf (" ");
     38       mpfr_print_raw (c);
     39     }
     40   res = mpfr_div (a, b, c, rnd_mode);
     41   if (ok)
     42     {
     43       printf (" ");
     44       mpfr_print_raw (a);
     45       printf ("\n");
     46     }
     47   return res;
     48 }
     49 #else
     50 #define test_div mpfr_div
     51 #endif
     52 
     53 #define check53(n, d, rnd, res) check4(n, d, rnd, 53, res)
     54 
     55 /* return 0 iff a and b are of the same sign */
     56 static int
     57 inex_cmp (int a, int b)
     58 {
     59   if (a > 0)
     60     return (b > 0) ? 0 : 1;
     61   else if (a == 0)
     62     return (b == 0) ? 0 : 1;
     63   else
     64     return (b < 0) ? 0 : 1;
     65 }
     66 
     67 static void
     68 check4 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, int p,
     69         const char *Qs)
     70 {
     71   mpfr_t q, n, d;
     72 
     73   mpfr_inits2 (p, q, n, d, (mpfr_ptr) 0);
     74   mpfr_set_str1 (n, Ns);
     75   mpfr_set_str1 (d, Ds);
     76   test_div(q, n, d, rnd_mode);
     77   if (mpfr_cmp_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN) )
     78     {
     79       printf ("mpfr_div failed for n=%s, d=%s, p=%d, rnd_mode=%s\n",
     80               Ns, Ds, p, mpfr_print_rnd_mode (rnd_mode));
     81       printf ("got      ");mpfr_print_binary(q);
     82       mpfr_set_str (q, Qs, ((p==53) ? 10 : 2), MPFR_RNDN);
     83       printf("\nexpected "); mpfr_print_binary(q);
     84       putchar('\n');
     85       exit (1);
     86     }
     87   mpfr_clears (q, n, d, (mpfr_ptr) 0);
     88 }
     89 
     90 static void
     91 check24 (const char *Ns, const char *Ds, mpfr_rnd_t rnd_mode, const char *Qs)
     92 {
     93   mpfr_t q, n, d;
     94 
     95   mpfr_inits2 (24, q, n, d, (mpfr_ptr) 0);
     96 
     97   mpfr_set_str1 (n, Ns);
     98   mpfr_set_str1 (d, Ds);
     99   test_div(q, n, d, rnd_mode);
    100   if (mpfr_cmp_str1 (q, Qs) )
    101     {
    102       printf ("mpfr_div failed for n=%s, d=%s, prec=24, rnd_mode=%s\n",
    103              Ns, Ds, mpfr_print_rnd_mode(rnd_mode));
    104       printf ("expected quotient is %s, got ", Qs);
    105       mpfr_out_str(stdout,10,0,q, MPFR_RNDN); putchar('\n');
    106       exit (1);
    107     }
    108   mpfr_clears (q, n, d, (mpfr_ptr) 0);
    109 }
    110 
    111 /* the following examples come from the paper "Number-theoretic Test
    112    Generation for Directed Rounding" from Michael Parks, Table 2 */
    113 static void
    114 check_float(void)
    115 {
    116   check24("70368760954880.0", "8388609.0", MPFR_RNDN, "8.388609e6");
    117   check24("140737479966720.0", "16777213.0", MPFR_RNDN, "8.388609e6");
    118   check24("70368777732096.0", "8388611.0", MPFR_RNDN, "8.388609e6");
    119   check24("105553133043712.0", "12582911.0", MPFR_RNDN, "8.38861e6");
    120   /* the exponent for the following example was forgotten in
    121      the Arith'14 version of Parks' paper */
    122   check24 ("12582913.0", "12582910.0", MPFR_RNDN, "1.000000238");
    123   check24 ("105553124655104.0", "12582910.0", MPFR_RNDN, "8388610.0");
    124   check24("140737479966720.0", "8388609.0", MPFR_RNDN, "1.6777213e7");
    125   check24("70368777732096.0", "8388609.0", MPFR_RNDN, "8.388611e6");
    126   check24("105553133043712.0", "8388610.0", MPFR_RNDN, "1.2582911e7");
    127   check24("105553124655104.0", "8388610.0", MPFR_RNDN, "1.258291e7");
    128 
    129   check24("70368760954880.0", "8388609.0", MPFR_RNDZ, "8.388608e6");
    130   check24("140737479966720.0", "16777213.0", MPFR_RNDZ, "8.388609e6");
    131   check24("70368777732096.0", "8388611.0", MPFR_RNDZ, "8.388608e6");
    132   check24("105553133043712.0", "12582911.0", MPFR_RNDZ, "8.38861e6");
    133   check24("12582913.0", "12582910.0", MPFR_RNDZ, "1.000000238");
    134   check24 ("105553124655104.0", "12582910.0", MPFR_RNDZ, "8388610.0");
    135   check24("140737479966720.0", "8388609.0", MPFR_RNDZ, "1.6777213e7");
    136   check24("70368777732096.0", "8388609.0", MPFR_RNDZ, "8.38861e6");
    137   check24("105553133043712.0", "8388610.0", MPFR_RNDZ, "1.2582911e7");
    138   check24("105553124655104.0", "8388610.0", MPFR_RNDZ, "1.258291e7");
    139 
    140   check24("70368760954880.0", "8388609.0", MPFR_RNDU, "8.388609e6");
    141   check24("140737479966720.0", "16777213.0", MPFR_RNDU, "8.38861e6");
    142   check24("70368777732096.0", "8388611.0", MPFR_RNDU, "8.388609e6");
    143   check24("105553133043712.0", "12582911.0", MPFR_RNDU, "8.388611e6");
    144   check24("12582913.0", "12582910.0", MPFR_RNDU, "1.000000357");
    145   check24 ("105553124655104.0", "12582910.0", MPFR_RNDU, "8388611.0");
    146   check24("140737479966720.0", "8388609.0", MPFR_RNDU, "1.6777214e7");
    147   check24("70368777732096.0", "8388609.0", MPFR_RNDU, "8.388611e6");
    148   check24("105553133043712.0", "8388610.0", MPFR_RNDU, "1.2582912e7");
    149   check24("105553124655104.0", "8388610.0", MPFR_RNDU, "1.2582911e7");
    150 
    151   check24("70368760954880.0", "8388609.0", MPFR_RNDD, "8.388608e6");
    152   check24("140737479966720.0", "16777213.0", MPFR_RNDD, "8.388609e6");
    153   check24("70368777732096.0", "8388611.0", MPFR_RNDD, "8.388608e6");
    154   check24("105553133043712.0", "12582911.0", MPFR_RNDD, "8.38861e6");
    155   check24("12582913.0", "12582910.0", MPFR_RNDD, "1.000000238");
    156   check24 ("105553124655104.0", "12582910.0", MPFR_RNDD, "8388610.0");
    157   check24("140737479966720.0", "8388609.0", MPFR_RNDD, "1.6777213e7");
    158   check24("70368777732096.0", "8388609.0", MPFR_RNDD, "8.38861e6");
    159   check24("105553133043712.0", "8388610.0", MPFR_RNDD, "1.2582911e7");
    160   check24("105553124655104.0", "8388610.0", MPFR_RNDD, "1.258291e7");
    161 
    162   check24("70368760954880.0", "8388609.0", MPFR_RNDA, "8.388609e6");
    163 }
    164 
    165 static void
    166 check_double(void)
    167 {
    168   check53("0.0", "1.0", MPFR_RNDZ, "0.0");
    169   check53("-7.4988969224688591e63", "4.8816866450288732e306", MPFR_RNDD,
    170           "-1.5361282826510687291e-243");
    171   check53("-1.33225773037748601769e+199", "3.63449540676937123913e+79",
    172           MPFR_RNDZ, "-3.6655920045905428978e119");
    173   check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDU,
    174           "1.6672003992376663654e-67");
    175   check53("9.89438396044940256501e-134", "5.93472984109987421717e-67",MPFR_RNDA,
    176           "1.6672003992376663654e-67");
    177   check53("9.89438396044940256501e-134", "-5.93472984109987421717e-67",
    178           MPFR_RNDU, "-1.6672003992376663654e-67");
    179   check53("-4.53063926135729747564e-308", "7.02293374921793516813e-84",
    180           MPFR_RNDD, "-6.4512060388748850857e-225");
    181   check53("6.25089225176473806123e-01","-2.35527154824420243364e-230",
    182           MPFR_RNDD, "-2.6540006635008291192e229");
    183   check53("6.25089225176473806123e-01","-2.35527154824420243364e-230",
    184           MPFR_RNDA, "-2.6540006635008291192e229");
    185   check53("6.52308934689126e15", "-1.62063546601505417497e273", MPFR_RNDN,
    186           "-4.0250194961676020848e-258");
    187   check53("1.04636807108079349236e-189", "3.72295730823253012954e-292",
    188           MPFR_RNDZ, "2.810583051186143125e102");
    189   /* problems found by Kevin under HP-PA */
    190   check53 ("2.861044553323177e-136", "-1.1120354257068143e+45", MPFR_RNDZ,
    191            "-2.5727998292003016e-181");
    192   check53 ("-4.0559157245809205e-127", "-1.1237723844524865e+77", MPFR_RNDN,
    193            "3.6091968273068081e-204");
    194   check53 ("-1.8177943561493235e-93", "-8.51233984260364e-104", MPFR_RNDU,
    195            "2.1354814184595821e+10");
    196 }
    197 
    198 static void
    199 check_64(void)
    200 {
    201   mpfr_t x,y,z;
    202 
    203   mpfr_inits2 (64, x, y, z, (mpfr_ptr) 0);
    204 
    205   mpfr_set_str_binary(x, "1.00100100110110101001010010101111000001011100100101010000000000E54");
    206   mpfr_set_str_binary(y, "1.00000000000000000000000000000000000000000000000000000000000000E584");
    207   test_div(z, x, y, MPFR_RNDU);
    208   if (mpfr_cmp_str (z, "0.1001001001101101010010100101011110000010111001001010100000000000E-529", 2, MPFR_RNDN))
    209     {
    210       printf("Error for tdiv for MPFR_RNDU and p=64\nx=");
    211       mpfr_print_binary(x);
    212       printf("\ny=");
    213       mpfr_print_binary(y);
    214       printf("\ngot      ");
    215       mpfr_print_binary(z);
    216       printf("\nexpected 0.1001001001101101010010100101011110000010111001001010100000000000E-529\n");
    217       exit(1);
    218     }
    219 
    220   mpfr_clears (x, y, z, (mpfr_ptr) 0);
    221 }
    222 
    223 static void
    224 check_convergence (void)
    225 {
    226   mpfr_t x, y; int i, j;
    227 
    228   mpfr_init2(x, 130);
    229   mpfr_set_str_binary(x, "0.1011111101011010101000001010011111101000011100011101010011111011000011001010000000111100100111110011001010110100100001001000111001E6944");
    230   mpfr_init2(y, 130);
    231   mpfr_set_ui(y, 5, MPFR_RNDN);
    232   test_div(x, x, y, MPFR_RNDD); /* exact division */
    233 
    234   mpfr_set_prec(x, 64);
    235   mpfr_set_prec(y, 64);
    236   mpfr_set_str_binary(x, "0.10010010011011010100101001010111100000101110010010101E55");
    237   mpfr_set_str_binary(y, "0.1E585");
    238   test_div(x, x, y, MPFR_RNDN);
    239   mpfr_set_str_binary(y, "0.10010010011011010100101001010111100000101110010010101E-529");
    240   if (mpfr_cmp (x, y))
    241     {
    242       printf ("Error in mpfr_div for prec=64, rnd=MPFR_RNDN\n");
    243       printf ("got        "); mpfr_print_binary(x); puts ("");
    244       printf ("instead of "); mpfr_print_binary(y); puts ("");
    245       exit(1);
    246     }
    247 
    248   for (i=32; i<=64; i+=32)
    249     {
    250       mpfr_set_prec(x, i);
    251       mpfr_set_prec(y, i);
    252       mpfr_set_ui(x, 1, MPFR_RNDN);
    253       RND_LOOP(j)
    254         {
    255           mpfr_set_ui (y, 1, MPFR_RNDN);
    256           test_div (y, x, y, (mpfr_rnd_t) j);
    257           if (mpfr_cmp_ui (y, 1))
    258             {
    259               printf ("mpfr_div failed for x=1.0, y=1.0, prec=%d rnd=%s\n",
    260                       i, mpfr_print_rnd_mode ((mpfr_rnd_t) j));
    261               printf ("got "); mpfr_print_binary(y); puts ("");
    262               exit (1);
    263             }
    264         }
    265     }
    266 
    267   mpfr_clear (x);
    268   mpfr_clear (y);
    269 }
    270 
    271 #define KMAX 10000
    272 
    273 /* given y = o(x/u), x, u, find the inexact flag by
    274    multiplying y by u */
    275 static int
    276 get_inexact (mpfr_t y, mpfr_t x, mpfr_t u)
    277 {
    278   mpfr_t xx;
    279   int inex;
    280   mpfr_init2 (xx, mpfr_get_prec (y) + mpfr_get_prec (u));
    281   mpfr_mul (xx, y, u, MPFR_RNDN); /* exact */
    282   inex = mpfr_cmp (xx, x);
    283   mpfr_clear (xx);
    284   return inex;
    285 }
    286 
    287 static void
    288 check_hard (void)
    289 {
    290   mpfr_t u, v, q, q2;
    291   mpfr_prec_t precu, precv, precq;
    292   int rnd;
    293   int inex, inex2, i, j;
    294 
    295   mpfr_init (q);
    296   mpfr_init (q2);
    297   mpfr_init (u);
    298   mpfr_init (v);
    299 
    300   for (precq = MPFR_PREC_MIN; precq <= 64; precq ++)
    301     {
    302       mpfr_set_prec (q, precq);
    303       mpfr_set_prec (q2, precq + 1);
    304       for (j = 0; j < 2; j++)
    305         {
    306           if (j == 0)
    307             {
    308               do
    309                 {
    310                   mpfr_urandomb (q2, RANDS);
    311                 }
    312               while (mpfr_cmp_ui (q2, 0) == 0);
    313             }
    314           else /* use q2=1 */
    315             mpfr_set_ui (q2, 1, MPFR_RNDN);
    316       for (precv = precq; precv <= 10 * precq; precv += precq)
    317         {
    318           mpfr_set_prec (v, precv);
    319           do
    320             {
    321               mpfr_urandomb (v, RANDS);
    322             }
    323           while (mpfr_cmp_ui (v, 0) == 0);
    324           for (precu = precq; precu <= 10 * precq; precu += precq)
    325             {
    326               mpfr_set_prec (u, precu);
    327               mpfr_mul (u, v, q2, MPFR_RNDN);
    328               mpfr_nextbelow (u);
    329               for (i = 0; i <= 2; i++)
    330                 {
    331                   RND_LOOP(rnd)
    332                     {
    333                       inex = test_div (q, u, v, (mpfr_rnd_t) rnd);
    334                       inex2 = get_inexact (q, u, v);
    335                       if (inex_cmp (inex, inex2))
    336                         {
    337                           printf ("Wrong inexact flag for rnd=%s: expected %d, got %d\n",
    338                                   mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), inex2, inex);
    339                           printf ("u=  "); mpfr_dump (u);
    340                           printf ("v=  "); mpfr_dump (v);
    341                           printf ("q=  "); mpfr_dump (q);
    342                           mpfr_set_prec (q2, precq + precv);
    343                           mpfr_mul (q2, q, v, MPFR_RNDN);
    344                           printf ("q*v="); mpfr_dump (q2);
    345                           exit (1);
    346                         }
    347                     }
    348                   mpfr_nextabove (u);
    349                 }
    350             }
    351         }
    352         }
    353     }
    354 
    355   mpfr_clear (q);
    356   mpfr_clear (q2);
    357   mpfr_clear (u);
    358   mpfr_clear (v);
    359 }
    360 
    361 static void
    362 check_lowr (void)
    363 {
    364   mpfr_t x, y, z, z2, z3, tmp;
    365   int k, c, c2;
    366 
    367 
    368   mpfr_init2 (x, 1000);
    369   mpfr_init2 (y, 100);
    370   mpfr_init2 (tmp, 850);
    371   mpfr_init2 (z, 10);
    372   mpfr_init2 (z2, 10);
    373   mpfr_init2 (z3, 50);
    374 
    375   for (k = 1; k < KMAX; k++)
    376     {
    377       do
    378         {
    379           mpfr_urandomb (z, RANDS);
    380         }
    381       while (mpfr_cmp_ui (z, 0) == 0);
    382       do
    383         {
    384           mpfr_urandomb (tmp, RANDS);
    385         }
    386       while (mpfr_cmp_ui (tmp, 0) == 0);
    387       mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */
    388       c = test_div (z2, x, tmp, MPFR_RNDN);
    389 
    390       if (c || mpfr_cmp (z2, z))
    391         {
    392           printf ("Error in mpfr_div rnd=MPFR_RNDN\n");
    393           printf ("got        "); mpfr_print_binary(z2); puts ("");
    394           printf ("instead of "); mpfr_print_binary(z); puts ("");
    395           printf ("inex flag = %d, expected 0\n", c);
    396           exit (1);
    397         }
    398     }
    399 
    400   /* x has still precision 1000, z precision 10, and tmp prec 850 */
    401   mpfr_set_prec (z2, 9);
    402   for (k = 1; k < KMAX; k++)
    403     {
    404       mpfr_urandomb (z, RANDS);
    405       do
    406         {
    407           mpfr_urandomb (tmp, RANDS);
    408         }
    409       while (mpfr_cmp_ui (tmp, 0) == 0);
    410       mpfr_mul (x, z, tmp, MPFR_RNDN); /* exact */
    411       c = test_div (z2, x, tmp, MPFR_RNDN);
    412       /* since z2 has one less bit that z, either the division is exact
    413          if z is representable on 9 bits, or we have an even round case */
    414 
    415       c2 = get_inexact (z2, x, tmp);
    416       if ((mpfr_cmp (z2, z) == 0 && c) || inex_cmp (c, c2))
    417         {
    418           printf ("Error in mpfr_div rnd=MPFR_RNDN\n");
    419           printf ("got        "); mpfr_print_binary(z2); puts ("");
    420           printf ("instead of "); mpfr_print_binary(z); puts ("");
    421           printf ("inex flag = %d, expected %d\n", c, c2);
    422           exit (1);
    423         }
    424       else if (c == 2)
    425         {
    426           mpfr_nexttoinf (z);
    427           if (mpfr_cmp(z2, z))
    428             {
    429               printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n");
    430               printf ("Dividing ");
    431               printf ("got        "); mpfr_print_binary(z2); puts ("");
    432               printf ("instead of "); mpfr_print_binary(z); puts ("");
    433               printf ("inex flag = %d\n", 1);
    434               exit (1);
    435             }
    436         }
    437       else if (c == -2)
    438         {
    439           mpfr_nexttozero (z);
    440           if (mpfr_cmp(z2, z))
    441             {
    442               printf ("Error in mpfr_div [even rnd?] rnd=MPFR_RNDN\n");
    443               printf ("Dividing ");
    444               printf ("got        "); mpfr_print_binary(z2); puts ("");
    445               printf ("instead of "); mpfr_print_binary(z); puts ("");
    446               printf ("inex flag = %d\n", 1);
    447               exit (1);
    448             }
    449         }
    450     }
    451 
    452   mpfr_set_prec(x, 1000);
    453   mpfr_set_prec(y, 100);
    454   mpfr_set_prec(tmp, 850);
    455   mpfr_set_prec(z, 10);
    456   mpfr_set_prec(z2, 10);
    457 
    458   /* almost exact divisions */
    459   for (k = 1; k < KMAX; k++)
    460     {
    461       do
    462         {
    463           mpfr_urandomb (z, RANDS);
    464         }
    465       while (mpfr_cmp_ui (z, 0) == 0);
    466       do
    467         {
    468           mpfr_urandomb (tmp, RANDS);
    469         }
    470       while (mpfr_cmp_ui (tmp, 0) == 0);
    471       mpfr_mul(x, z, tmp, MPFR_RNDN);
    472       mpfr_set(y, tmp, MPFR_RNDD);
    473       mpfr_nexttoinf (x);
    474 
    475       c = test_div(z2, x, y, MPFR_RNDD);
    476       test_div(z3, x, y, MPFR_RNDD);
    477       mpfr_set(z, z3, MPFR_RNDD);
    478 
    479       if (c != -1 || mpfr_cmp(z2, z))
    480         {
    481           printf ("Error in mpfr_div rnd=MPFR_RNDD\n");
    482           printf ("got        "); mpfr_print_binary(z2); puts ("");
    483           printf ("instead of "); mpfr_print_binary(z); puts ("");
    484           printf ("inex flag = %d\n", c);
    485           exit (1);
    486         }
    487 
    488       mpfr_set (y, tmp, MPFR_RNDU);
    489       test_div (z3, x, y, MPFR_RNDU);
    490       mpfr_set (z, z3, MPFR_RNDU);
    491       c = test_div (z2, x, y, MPFR_RNDU);
    492       if (c != 1 || mpfr_cmp (z2, z))
    493         {
    494           printf ("Error in mpfr_div rnd=MPFR_RNDU\n");
    495           printf ("u="); mpfr_dump (x);
    496           printf ("v="); mpfr_dump (y);
    497           printf ("got        "); mpfr_print_binary (z2); puts ("");
    498           printf ("instead of "); mpfr_print_binary (z); puts ("");
    499           printf ("inex flag = %d\n", c);
    500           exit (1);
    501         }
    502     }
    503 
    504   mpfr_clear (x);
    505   mpfr_clear (y);
    506   mpfr_clear (z);
    507   mpfr_clear (z2);
    508   mpfr_clear (z3);
    509   mpfr_clear (tmp);
    510 }
    511 
    512 #define MAX_PREC 128
    513 
    514 static void
    515 check_inexact (void)
    516 {
    517   mpfr_t x, y, z, u;
    518   mpfr_prec_t px, py, pu;
    519   int inexact, cmp;
    520   mpfr_rnd_t rnd;
    521 
    522   mpfr_init (x);
    523   mpfr_init (y);
    524   mpfr_init (z);
    525   mpfr_init (u);
    526 
    527   mpfr_set_prec (x, 28);
    528   mpfr_set_prec (y, 28);
    529   mpfr_set_prec (z, 1023);
    530   mpfr_set_str_binary (x, "0.1000001001101101111100010011E0");
    531   mpfr_set_str (z, "48284762641021308813686974720835219181653367326353400027913400579340343320519877153813133510034402932651132854764198688352364361009429039801248971901380781746767119334993621199563870113045276395603170432175354501451429471578325545278975153148347684600400321033502982713296919861760382863826626093689036010394", 10, MPFR_RNDN);
    532   mpfr_div (x, x, z, MPFR_RNDN);
    533   mpfr_set_str_binary (y, "0.1111001011001101001001111100E-1023");
    534   if (mpfr_cmp (x, y))
    535     {
    536       printf ("Error in mpfr_div for prec=28, RNDN\n");
    537       printf ("Expected "); mpfr_dump (y);
    538       printf ("Got      "); mpfr_dump (x);
    539       exit (1);
    540     }
    541 
    542   mpfr_set_prec (x, 53);
    543   mpfr_set_str_binary (x, "0.11101100110010100011011000000100001111011111110010101E0");
    544   mpfr_set_prec (u, 127);
    545   mpfr_set_str_binary (u, "0.1000001100110110110101110110101101111000110000001111111110000000011111001010110100110010111111111101000001011011101011101101000E-2");
    546   mpfr_set_prec (y, 95);
    547   inexact = test_div (y, x, u, MPFR_RNDN);
    548   if (inexact != (cmp = get_inexact (y, x, u)))
    549     {
    550       printf ("Wrong inexact flag (0): expected %d, got %d\n", cmp, inexact);
    551       printf ("x="); mpfr_out_str (stdout, 10, 99, x, MPFR_RNDN); printf ("\n");
    552       printf ("u="); mpfr_out_str (stdout, 10, 99, u, MPFR_RNDN); printf ("\n");
    553       printf ("y="); mpfr_out_str (stdout, 10, 99, y, MPFR_RNDN); printf ("\n");
    554       exit (1);
    555     }
    556 
    557   mpfr_set_prec (x, 33);
    558   mpfr_set_str_binary (x, "0.101111100011011101010011101100001E0");
    559   mpfr_set_prec (u, 2);
    560   mpfr_set_str_binary (u, "0.1E0");
    561   mpfr_set_prec (y, 28);
    562   if ((inexact = test_div (y, x, u, MPFR_RNDN) >= 0))
    563     {
    564       printf ("Wrong inexact flag (1): expected -1, got %d\n",
    565               inexact);
    566       exit (1);
    567     }
    568 
    569   mpfr_set_prec (x, 129);
    570   mpfr_set_str_binary (x, "0.111110101111001100000101011100101100110011011101010001000110110101100101000010000001110110100001101010001010100010001111001101010E-2");
    571   mpfr_set_prec (u, 15);
    572   mpfr_set_str_binary (u, "0.101101000001100E-1");
    573   mpfr_set_prec (y, 92);
    574   if ((inexact = test_div (y, x, u, MPFR_RNDN)) <= 0)
    575     {
    576       printf ("Wrong inexact flag for rnd=MPFR_RNDN(1): expected 1, got %d\n",
    577               inexact);
    578       mpfr_dump (x);
    579       mpfr_dump (u);
    580       mpfr_dump (y);
    581       exit (1);
    582     }
    583 
    584   for (px=2; px<MAX_PREC; px++)
    585     {
    586       mpfr_set_prec (x, px);
    587       mpfr_urandomb (x, RANDS);
    588       for (pu=2; pu<=MAX_PREC; pu++)
    589         {
    590           mpfr_set_prec (u, pu);
    591           do { mpfr_urandomb (u, RANDS); } while (mpfr_cmp_ui (u, 0) == 0);
    592             {
    593               py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - MPFR_PREC_MIN));
    594               mpfr_set_prec (y, py);
    595               mpfr_set_prec (z, py + pu);
    596                 {
    597                   rnd = RND_RAND ();
    598                   inexact = test_div (y, x, u, rnd);
    599                   if (mpfr_mul (z, y, u, rnd))
    600                     {
    601                       printf ("z <- y * u should be exact\n");
    602                       exit (1);
    603                     }
    604                   cmp = mpfr_cmp (z, x);
    605                   if (((inexact == 0) && (cmp != 0)) ||
    606                       ((inexact > 0) && (cmp <= 0)) ||
    607                       ((inexact < 0) && (cmp >= 0)))
    608                     {
    609                       printf ("Wrong inexact flag for rnd=%s\n",
    610                               mpfr_print_rnd_mode(rnd));
    611                       printf ("expected %d, got %d\n", cmp, inexact);
    612                       printf ("x="); mpfr_print_binary (x); puts ("");
    613                       printf ("u="); mpfr_print_binary (u); puts ("");
    614                       printf ("y="); mpfr_print_binary (y); puts ("");
    615                       printf ("y*u="); mpfr_print_binary (z); puts ("");
    616                       exit (1);
    617                     }
    618                 }
    619             }
    620         }
    621     }
    622 
    623   mpfr_clear (x);
    624   mpfr_clear (y);
    625   mpfr_clear (z);
    626   mpfr_clear (u);
    627 }
    628 
    629 static void
    630 check_nan (void)
    631 {
    632   mpfr_t  a, d, q;
    633   mpfr_exp_t emax, emin;
    634   int i;
    635 
    636   mpfr_init2 (a, 100L);
    637   mpfr_init2 (d, 100L);
    638   mpfr_init2 (q, 100L);
    639 
    640   /* 1/nan == nan */
    641   mpfr_set_ui (a, 1L, MPFR_RNDN);
    642   MPFR_SET_NAN (d);
    643   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    644   MPFR_ASSERTN (mpfr_nan_p (q));
    645 
    646   /* nan/1 == nan */
    647   MPFR_SET_NAN (a);
    648   mpfr_set_ui (d, 1L, MPFR_RNDN);
    649   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    650   MPFR_ASSERTN (mpfr_nan_p (q));
    651 
    652   /* +inf/1 == +inf */
    653   MPFR_SET_INF (a);
    654   MPFR_SET_POS (a);
    655   mpfr_set_ui (d, 1L, MPFR_RNDN);
    656   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    657   MPFR_ASSERTN (mpfr_inf_p (q));
    658   MPFR_ASSERTN (mpfr_sgn (q) > 0);
    659 
    660   /* 1/+inf == 0 */
    661   mpfr_set_ui (a, 1L, MPFR_RNDN);
    662   MPFR_SET_INF (d);
    663   MPFR_SET_POS (d);
    664   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    665   MPFR_ASSERTN (mpfr_number_p (q));
    666   MPFR_ASSERTN (mpfr_sgn (q) == 0);
    667 
    668   /* 0/0 == nan */
    669   mpfr_set_ui (a, 0L, MPFR_RNDN);
    670   mpfr_set_ui (d, 0L, MPFR_RNDN);
    671   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    672   MPFR_ASSERTN (mpfr_nan_p (q));
    673 
    674   /* +inf/+inf == nan */
    675   MPFR_SET_INF (a);
    676   MPFR_SET_POS (a);
    677   MPFR_SET_INF (d);
    678   MPFR_SET_POS (d);
    679   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    680   MPFR_ASSERTN (mpfr_nan_p (q));
    681 
    682   /* 1/+0 = +Inf */
    683   mpfr_set_ui (a, 1, MPFR_RNDZ);
    684   mpfr_set_ui (d, 0, MPFR_RNDZ);
    685   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    686   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
    687 
    688   /* 1/-0 = -Inf */
    689   mpfr_set_ui (a, 1, MPFR_RNDZ);
    690   mpfr_set_ui (d, 0, MPFR_RNDZ);
    691   mpfr_neg (d, d, MPFR_RNDZ);
    692   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    693   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
    694 
    695   /* -1/+0 = -Inf */
    696   mpfr_set_si (a, -1, MPFR_RNDZ);
    697   mpfr_set_ui (d, 0, MPFR_RNDZ);
    698   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    699   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
    700 
    701   /* -1/-0 = +Inf */
    702   mpfr_set_si (a, -1, MPFR_RNDZ);
    703   mpfr_set_ui (d, 0, MPFR_RNDZ);
    704   mpfr_neg (d, d, MPFR_RNDZ);
    705   MPFR_ASSERTN (test_div (q, a, d, MPFR_RNDZ) == 0); /* exact */
    706   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
    707 
    708   /* check overflow */
    709   emax = mpfr_get_emax ();
    710   set_emax (1);
    711   mpfr_set_ui (a, 1, MPFR_RNDZ);
    712   mpfr_set_ui (d, 1, MPFR_RNDZ);
    713   mpfr_div_2exp (d, d, 1, MPFR_RNDZ);
    714   test_div (q, a, d, MPFR_RNDU); /* 1 / 0.5 = 2 -> overflow */
    715   MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
    716   set_emax (emax);
    717 
    718   /* check underflow */
    719   emin = mpfr_get_emin ();
    720   set_emin (-1);
    721   mpfr_set_ui (a, 1, MPFR_RNDZ);
    722   mpfr_div_2exp (a, a, 2, MPFR_RNDZ);
    723   mpfr_set_prec (d, mpfr_get_prec (q) + 8);
    724   for (i = -1; i <= 1; i++)
    725     {
    726       int sign;
    727 
    728       /* Test 2^(-2) / (+/- (2 + eps)), with eps < 0, eps = 0, eps > 0.
    729          -> underflow.
    730          With div.c r5513, this test fails for eps > 0 in MPFR_RNDN. */
    731       mpfr_set_ui (d, 2, MPFR_RNDZ);
    732       if (i < 0)
    733         mpfr_nextbelow (d);
    734       if (i > 0)
    735         mpfr_nextabove (d);
    736       for (sign = 0; sign <= 1; sign++)
    737         {
    738           mpfr_clear_flags ();
    739           test_div (q, a, d, MPFR_RNDZ); /* result = 0 */
    740           MPFR_ASSERTN (mpfr_underflow_p ());
    741           MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
    742           MPFR_ASSERTN (MPFR_IS_ZERO (q));
    743           mpfr_clear_flags ();
    744           test_div (q, a, d, MPFR_RNDN); /* result = 0 iff eps >= 0 */
    745           MPFR_ASSERTN (mpfr_underflow_p ());
    746           MPFR_ASSERTN (sign ? MPFR_IS_NEG (q) : MPFR_IS_POS (q));
    747           if (i < 0)
    748             mpfr_nexttozero (q);
    749           MPFR_ASSERTN (MPFR_IS_ZERO (q));
    750           mpfr_neg (d, d, MPFR_RNDN);
    751         }
    752     }
    753   set_emin (emin);
    754 
    755   mpfr_clear (a);
    756   mpfr_clear (d);
    757   mpfr_clear (q);
    758 }
    759 
    760 static void
    761 consistency (void)
    762 {
    763   mpfr_t x, y, z1, z2;
    764   int i;
    765 
    766   mpfr_inits (x, y, z1, z2, (mpfr_ptr) 0);
    767 
    768   for (i = 0; i < 10000; i++)
    769     {
    770       mpfr_rnd_t rnd;
    771       mpfr_prec_t px, py, pz, p;
    772       int inex1, inex2;
    773 
    774       rnd = RND_RAND ();
    775       px = (randlimb () % 256) + 2;
    776       py = (randlimb () % 128) + 2;
    777       pz = (randlimb () % 256) + 2;
    778       mpfr_set_prec (x, px);
    779       mpfr_set_prec (y, py);
    780       mpfr_set_prec (z1, pz);
    781       mpfr_set_prec (z2, pz);
    782       mpfr_urandomb (x, RANDS);
    783       do
    784         mpfr_urandomb (y, RANDS);
    785       while (mpfr_zero_p (y));
    786       inex1 = mpfr_div (z1, x, y, rnd);
    787       MPFR_ASSERTN (!MPFR_IS_NAN (z1));
    788       p = MAX (MAX (px, py), pz);
    789       if (mpfr_prec_round (x, p, MPFR_RNDN) != 0 ||
    790           mpfr_prec_round (y, p, MPFR_RNDN) != 0)
    791         {
    792           printf ("mpfr_prec_round error for i = %d\n", i);
    793           exit (1);
    794         }
    795       inex2 = mpfr_div (z2, x, y, rnd);
    796       MPFR_ASSERTN (!MPFR_IS_NAN (z2));
    797       if (inex1 != inex2 || mpfr_cmp (z1, z2) != 0)
    798         {
    799           printf ("Consistency error for i = %d\n", i);
    800           exit (1);
    801         }
    802     }
    803 
    804   mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
    805 }
    806 
    807 /* Reported by Carl Witty on 2007-06-03 */
    808 static void
    809 test_20070603 (void)
    810 {
    811   mpfr_t n, d, q, c;
    812 
    813   mpfr_init2 (n, 128);
    814   mpfr_init2 (d, 128);
    815   mpfr_init2 (q, 31);
    816   mpfr_init2 (c, 31);
    817 
    818   mpfr_set_str (n, "10384593717069655257060992206846485", 10, MPFR_RNDN);
    819   mpfr_set_str (d, "10384593717069655257060992206847132", 10, MPFR_RNDN);
    820   mpfr_div (q, n, d, MPFR_RNDU);
    821 
    822   mpfr_set_ui (c, 1, MPFR_RNDN);
    823   if (mpfr_cmp (q, c) != 0)
    824     {
    825       printf ("Error in test_20070603\nGot        ");
    826       mpfr_dump (q);
    827       printf ("instead of ");
    828       mpfr_dump (c);
    829       exit (1);
    830     }
    831 
    832   /* same for 64-bit machines */
    833   mpfr_set_prec (n, 256);
    834   mpfr_set_prec (d, 256);
    835   mpfr_set_prec (q, 63);
    836   mpfr_set_str (n, "822752278660603021077484591278675252491367930877209729029898240", 10, MPFR_RNDN);
    837   mpfr_set_str (d, "822752278660603021077484591278675252491367930877212507873738752", 10, MPFR_RNDN);
    838   mpfr_div (q, n, d, MPFR_RNDU);
    839   if (mpfr_cmp (q, c) != 0)
    840     {
    841       printf ("Error in test_20070603\nGot        ");
    842       mpfr_dump (q);
    843       printf ("instead of ");
    844       mpfr_dump (c);
    845       exit (1);
    846     }
    847 
    848   mpfr_clear (n);
    849   mpfr_clear (d);
    850   mpfr_clear (q);
    851   mpfr_clear (c);
    852 }
    853 
    854 /* Bug found while adding tests for mpfr_cot */
    855 static void
    856 test_20070628 (void)
    857 {
    858   mpfr_exp_t old_emax;
    859   mpfr_t x, y;
    860   int inex, err = 0;
    861 
    862   old_emax = mpfr_get_emax ();
    863 
    864   if (mpfr_set_emax (256))
    865     {
    866       printf ("Can't change exponent range\n");
    867       exit (1);
    868     }
    869 
    870   mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
    871   mpfr_set_si (x, -1, MPFR_RNDN);
    872   mpfr_set_si_2exp (y, 1, -256, MPFR_RNDN);
    873   mpfr_clear_flags ();
    874   inex = mpfr_div (x, x, y, MPFR_RNDD);
    875   if (MPFR_SIGN (x) >= 0 || ! mpfr_inf_p (x))
    876     {
    877       printf ("Error in test_20070628: expected -Inf, got\n");
    878       mpfr_dump (x);
    879       err++;
    880     }
    881   if (inex >= 0)
    882     {
    883       printf ("Error in test_20070628: expected inex < 0, got %d\n", inex);
    884       err++;
    885     }
    886   if (! mpfr_overflow_p ())
    887     {
    888       printf ("Error in test_20070628: overflow flag is not set\n");
    889       err++;
    890     }
    891   mpfr_clears (x, y, (mpfr_ptr) 0);
    892   mpfr_set_emax (old_emax);
    893 }
    894 
    895 #define TEST_FUNCTION test_div
    896 #define TWO_ARGS
    897 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
    898 #include "tgeneric.c"
    899 
    900 int
    901 main (int argc, char *argv[])
    902 {
    903   tests_start_mpfr ();
    904 
    905   check_inexact ();
    906   check_hard ();
    907   check_nan ();
    908   check_lowr ();
    909   check_float (); /* checks single precision */
    910   check_double ();
    911   check_convergence ();
    912   check_64 ();
    913 
    914   check4("4.0","4.503599627370496e15", MPFR_RNDZ, 62,
    915    "0.10000000000000000000000000000000000000000000000000000000000000E-49");
    916   check4("1.0","2.10263340267725788209e+187", MPFR_RNDU, 65,
    917    "0.11010011111001101011111001100111110100000001101001111100111000000E-622");
    918   check4("2.44394909079968374564e-150", "2.10263340267725788209e+187",MPFR_RNDU,
    919          65,
    920   "0.11010011111001101011111001100111110100000001101001111100111000000E-1119");
    921 
    922   consistency ();
    923   test_20070603 ();
    924   test_20070628 ();
    925   test_generic (2, 800, 50);
    926 
    927   tests_end_mpfr ();
    928   return 0;
    929 }
    930