Home | History | Annotate | Line # | Download | only in tests
tmul.c revision 1.1
      1  1.1  mrg /* Test file for mpfr_mul.
      2  1.1  mrg 
      3  1.1  mrg Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
      4  1.1  mrg Contributed by the Arenaire and Cacao projects, INRIA.
      5  1.1  mrg 
      6  1.1  mrg This file is part of the GNU MPFR Library.
      7  1.1  mrg 
      8  1.1  mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9  1.1  mrg it under the terms of the GNU Lesser General Public License as published by
     10  1.1  mrg the Free Software Foundation; either version 3 of the License, or (at your
     11  1.1  mrg option) any later version.
     12  1.1  mrg 
     13  1.1  mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15  1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16  1.1  mrg License for more details.
     17  1.1  mrg 
     18  1.1  mrg You should have received a copy of the GNU Lesser General Public License
     19  1.1  mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20  1.1  mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21  1.1  mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22  1.1  mrg 
     23  1.1  mrg #include <stdio.h>
     24  1.1  mrg #include <stdlib.h>
     25  1.1  mrg 
     26  1.1  mrg #include "mpfr-test.h"
     27  1.1  mrg 
     28  1.1  mrg #ifdef CHECK_EXTERNAL
     29  1.1  mrg static int
     30  1.1  mrg test_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
     31  1.1  mrg {
     32  1.1  mrg   int res;
     33  1.1  mrg   int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
     34  1.1  mrg   if (ok)
     35  1.1  mrg     {
     36  1.1  mrg       mpfr_print_raw (b);
     37  1.1  mrg       printf (" ");
     38  1.1  mrg       mpfr_print_raw (c);
     39  1.1  mrg     }
     40  1.1  mrg   res = mpfr_mul (a, b, c, rnd_mode);
     41  1.1  mrg   if (ok)
     42  1.1  mrg     {
     43  1.1  mrg       printf (" ");
     44  1.1  mrg       mpfr_print_raw (a);
     45  1.1  mrg       printf ("\n");
     46  1.1  mrg     }
     47  1.1  mrg   return res;
     48  1.1  mrg }
     49  1.1  mrg #else
     50  1.1  mrg #define test_mul mpfr_mul
     51  1.1  mrg #endif
     52  1.1  mrg 
     53  1.1  mrg /* checks that xs * ys gives the expected result res */
     54  1.1  mrg static void
     55  1.1  mrg check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode,
     56  1.1  mrg         unsigned int px, unsigned int py, unsigned int pz, const char *res)
     57  1.1  mrg {
     58  1.1  mrg   mpfr_t xx, yy, zz;
     59  1.1  mrg 
     60  1.1  mrg   mpfr_init2 (xx, px);
     61  1.1  mrg   mpfr_init2 (yy, py);
     62  1.1  mrg   mpfr_init2 (zz, pz);
     63  1.1  mrg   mpfr_set_str1 (xx, xs);
     64  1.1  mrg   mpfr_set_str1 (yy, ys);
     65  1.1  mrg   test_mul(zz, xx, yy, rnd_mode);
     66  1.1  mrg   if (mpfr_cmp_str1 (zz, res) )
     67  1.1  mrg     {
     68  1.1  mrg       printf ("(1)mpfr_mul failed for x=%s y=%s with rnd=%s\n",
     69  1.1  mrg               xs, ys, mpfr_print_rnd_mode (rnd_mode));
     70  1.1  mrg       printf ("correct is %s, mpfr_mul gives ", res);
     71  1.1  mrg       mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
     72  1.1  mrg       /*
     73  1.1  mrg         printf("\nBinary forms:\nxx=");
     74  1.1  mrg         mpfr_print_binary (xx);
     75  1.1  mrg         printf("\nyy=");
     76  1.1  mrg         mpfr_print_binary (yy);
     77  1.1  mrg         printf("\nzz=");
     78  1.1  mrg         mpfr_print_binary(zz);
     79  1.1  mrg         printf("\nre=");
     80  1.1  mrg         mpfr_set_str1 (zz, res);
     81  1.1  mrg         mpfr_print_binary(zz);
     82  1.1  mrg         putchar('\n');*/
     83  1.1  mrg       exit (1);
     84  1.1  mrg     }
     85  1.1  mrg   mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
     86  1.1  mrg }
     87  1.1  mrg 
     88  1.1  mrg static void
     89  1.1  mrg check53 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs)
     90  1.1  mrg {
     91  1.1  mrg   mpfr_t xx, yy, zz;
     92  1.1  mrg 
     93  1.1  mrg   mpfr_inits2 (53, xx, yy, zz, (mpfr_ptr) 0);
     94  1.1  mrg   mpfr_set_str1 (xx, xs);
     95  1.1  mrg   mpfr_set_str1 (yy, ys);
     96  1.1  mrg   test_mul (zz, xx, yy, rnd_mode);
     97  1.1  mrg   if (mpfr_cmp_str1 (zz, zs) )
     98  1.1  mrg     {
     99  1.1  mrg       printf ("(2) mpfr_mul failed for x=%s y=%s with rnd=%s\n",
    100  1.1  mrg               xs, ys, mpfr_print_rnd_mode(rnd_mode));
    101  1.1  mrg       printf ("correct result is %s,\n mpfr_mul gives ", zs);
    102  1.1  mrg       mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
    103  1.1  mrg       /*
    104  1.1  mrg         printf("\nBinary forms:\nxx=");
    105  1.1  mrg         mpfr_print_binary (xx);
    106  1.1  mrg         printf("\nyy=");
    107  1.1  mrg         mpfr_print_binary (yy);
    108  1.1  mrg         printf("\nzz=");
    109  1.1  mrg         mpfr_print_binary(zz);
    110  1.1  mrg         printf("\nre=");
    111  1.1  mrg         mpfr_set_str1 (zz, zs);
    112  1.1  mrg         mpfr_print_binary(zz);
    113  1.1  mrg         putchar('\n'); */
    114  1.1  mrg       exit (1);
    115  1.1  mrg     }
    116  1.1  mrg   mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
    117  1.1  mrg }
    118  1.1  mrg 
    119  1.1  mrg /* checks that x*y gives the right result with 24 bits of precision */
    120  1.1  mrg static void
    121  1.1  mrg check24 (const char *xs, const char *ys, mpfr_rnd_t rnd_mode, const char *zs)
    122  1.1  mrg {
    123  1.1  mrg   mpfr_t xx, yy, zz;
    124  1.1  mrg 
    125  1.1  mrg   mpfr_inits2 (24, xx, yy, zz, (mpfr_ptr) 0);
    126  1.1  mrg   mpfr_set_str1 (xx, xs);
    127  1.1  mrg   mpfr_set_str1 (yy, ys);
    128  1.1  mrg   test_mul (zz, xx, yy, rnd_mode);
    129  1.1  mrg   if (mpfr_cmp_str1 (zz, zs) )
    130  1.1  mrg     {
    131  1.1  mrg       printf ("(3) mpfr_mul failed for x=%s y=%s with "
    132  1.1  mrg               "rnd=%s\n", xs, ys, mpfr_print_rnd_mode(rnd_mode));
    133  1.1  mrg       printf ("correct result is gives %s, mpfr_mul gives ", zs);
    134  1.1  mrg       mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
    135  1.1  mrg       putchar('\n');
    136  1.1  mrg       exit (1);
    137  1.1  mrg     }
    138  1.1  mrg   mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
    139  1.1  mrg }
    140  1.1  mrg 
    141  1.1  mrg /* the following examples come from the paper "Number-theoretic Test
    142  1.1  mrg    Generation for Directed Rounding" from Michael Parks, Table 1 */
    143  1.1  mrg static void
    144  1.1  mrg check_float (void)
    145  1.1  mrg {
    146  1.1  mrg   check24("8388609.0",  "8388609.0", MPFR_RNDN, "70368760954880.0");
    147  1.1  mrg   check24("16777213.0", "8388609.0", MPFR_RNDN, "140737479966720.0");
    148  1.1  mrg   check24("8388611.0",  "8388609.0", MPFR_RNDN, "70368777732096.0");
    149  1.1  mrg   check24("12582911.0", "8388610.0", MPFR_RNDN, "105553133043712.0");
    150  1.1  mrg   check24("12582914.0", "8388610.0", MPFR_RNDN, "105553158209536.0");
    151  1.1  mrg   check24("13981013.0", "8388611.0", MPFR_RNDN, "117281279442944.0");
    152  1.1  mrg   check24("11184811.0", "8388611.0", MPFR_RNDN, "93825028587520.0");
    153  1.1  mrg   check24("11184810.0", "8388611.0", MPFR_RNDN, "93825020198912.0");
    154  1.1  mrg   check24("13981014.0", "8388611.0", MPFR_RNDN, "117281287831552.0");
    155  1.1  mrg 
    156  1.1  mrg   check24("8388609.0",  "8388609.0", MPFR_RNDZ, "70368760954880.0");
    157  1.1  mrg   check24("16777213.0", "8388609.0", MPFR_RNDZ, "140737471578112.0");
    158  1.1  mrg   check24("8388611.0",  "8388609.0", MPFR_RNDZ, "70368777732096.0");
    159  1.1  mrg   check24("12582911.0", "8388610.0", MPFR_RNDZ, "105553124655104.0");
    160  1.1  mrg   check24("12582914.0", "8388610.0", MPFR_RNDZ, "105553158209536.0");
    161  1.1  mrg   check24("13981013.0", "8388611.0", MPFR_RNDZ, "117281271054336.0");
    162  1.1  mrg   check24("11184811.0", "8388611.0", MPFR_RNDZ, "93825028587520.0");
    163  1.1  mrg   check24("11184810.0", "8388611.0", MPFR_RNDZ, "93825011810304.0");
    164  1.1  mrg   check24("13981014.0", "8388611.0", MPFR_RNDZ, "117281287831552.0");
    165  1.1  mrg 
    166  1.1  mrg   check24("8388609.0",  "8388609.0", MPFR_RNDU, "70368769343488.0");
    167  1.1  mrg   check24("16777213.0", "8388609.0", MPFR_RNDU, "140737479966720.0");
    168  1.1  mrg   check24("8388611.0",  "8388609.0", MPFR_RNDU, "70368786120704.0");
    169  1.1  mrg   check24("12582911.0", "8388610.0", MPFR_RNDU, "105553133043712.0");
    170  1.1  mrg   check24("12582914.0", "8388610.0", MPFR_RNDU, "105553166598144.0");
    171  1.1  mrg   check24("13981013.0", "8388611.0", MPFR_RNDU, "117281279442944.0");
    172  1.1  mrg   check24("11184811.0", "8388611.0", MPFR_RNDU, "93825036976128.0");
    173  1.1  mrg   check24("11184810.0", "8388611.0", MPFR_RNDU, "93825020198912.0");
    174  1.1  mrg   check24("13981014.0", "8388611.0", MPFR_RNDU, "117281296220160.0");
    175  1.1  mrg 
    176  1.1  mrg   check24("8388609.0",  "8388609.0", MPFR_RNDD, "70368760954880.0");
    177  1.1  mrg   check24("16777213.0", "8388609.0", MPFR_RNDD, "140737471578112.0");
    178  1.1  mrg   check24("8388611.0",  "8388609.0", MPFR_RNDD, "70368777732096.0");
    179  1.1  mrg   check24("12582911.0", "8388610.0", MPFR_RNDD, "105553124655104.0");
    180  1.1  mrg   check24("12582914.0", "8388610.0", MPFR_RNDD, "105553158209536.0");
    181  1.1  mrg   check24("13981013.0", "8388611.0", MPFR_RNDD, "117281271054336.0");
    182  1.1  mrg   check24("11184811.0", "8388611.0", MPFR_RNDD, "93825028587520.0");
    183  1.1  mrg   check24("11184810.0", "8388611.0", MPFR_RNDD, "93825011810304.0");
    184  1.1  mrg   check24("13981014.0", "8388611.0", MPFR_RNDD, "117281287831552.0");
    185  1.1  mrg }
    186  1.1  mrg 
    187  1.1  mrg /* check sign of result */
    188  1.1  mrg static void
    189  1.1  mrg check_sign (void)
    190  1.1  mrg {
    191  1.1  mrg   mpfr_t a, b;
    192  1.1  mrg 
    193  1.1  mrg   mpfr_init2 (a, 53);
    194  1.1  mrg   mpfr_init2 (b, 53);
    195  1.1  mrg   mpfr_set_si (a, -1, MPFR_RNDN);
    196  1.1  mrg   mpfr_set_ui (b, 2, MPFR_RNDN);
    197  1.1  mrg   test_mul(a, b, b, MPFR_RNDN);
    198  1.1  mrg   if (mpfr_cmp_ui (a, 4) )
    199  1.1  mrg     {
    200  1.1  mrg       printf ("2.0*2.0 gives \n");
    201  1.1  mrg       mpfr_out_str(stdout, 10, 0, a, MPFR_RNDN);
    202  1.1  mrg       putchar('\n');
    203  1.1  mrg       exit (1);
    204  1.1  mrg     }
    205  1.1  mrg   mpfr_clear(a); mpfr_clear(b);
    206  1.1  mrg }
    207  1.1  mrg 
    208  1.1  mrg /* checks that the inexact return value is correct */
    209  1.1  mrg static void
    210  1.1  mrg check_exact (void)
    211  1.1  mrg {
    212  1.1  mrg   mpfr_t a, b, c, d;
    213  1.1  mrg   mpfr_prec_t prec;
    214  1.1  mrg   int i, inexact;
    215  1.1  mrg   mpfr_rnd_t rnd;
    216  1.1  mrg 
    217  1.1  mrg   mpfr_init (a);
    218  1.1  mrg   mpfr_init (b);
    219  1.1  mrg   mpfr_init (c);
    220  1.1  mrg   mpfr_init (d);
    221  1.1  mrg 
    222  1.1  mrg   mpfr_set_prec (a, 17);
    223  1.1  mrg   mpfr_set_prec (b, 17);
    224  1.1  mrg   mpfr_set_prec (c, 32);
    225  1.1  mrg   mpfr_set_str_binary (a, "1.1000111011000100e-1");
    226  1.1  mrg   mpfr_set_str_binary (b, "1.0010001111100111e-1");
    227  1.1  mrg   if (test_mul (c, a, b, MPFR_RNDZ))
    228  1.1  mrg     {
    229  1.1  mrg       printf ("wrong return value (1)\n");
    230  1.1  mrg       exit (1);
    231  1.1  mrg     }
    232  1.1  mrg 
    233  1.1  mrg   for (prec = 2; prec < 100; prec++)
    234  1.1  mrg     {
    235  1.1  mrg       mpfr_set_prec (a, prec);
    236  1.1  mrg       mpfr_set_prec (b, prec);
    237  1.1  mrg       mpfr_set_prec (c, 2 * prec - 2);
    238  1.1  mrg       mpfr_set_prec (d, 2 * prec);
    239  1.1  mrg       for (i = 0; i < 1000; i++)
    240  1.1  mrg         {
    241  1.1  mrg           mpfr_urandomb (a, RANDS);
    242  1.1  mrg           mpfr_urandomb (b, RANDS);
    243  1.1  mrg           rnd = RND_RAND ();
    244  1.1  mrg           inexact = test_mul (c, a, b, rnd);
    245  1.1  mrg           if (test_mul (d, a, b, rnd)) /* should be always exact */
    246  1.1  mrg             {
    247  1.1  mrg               printf ("unexpected inexact return value\n");
    248  1.1  mrg               exit (1);
    249  1.1  mrg             }
    250  1.1  mrg           if ((inexact == 0) && mpfr_cmp (c, d))
    251  1.1  mrg             {
    252  1.1  mrg               printf ("inexact=0 but results differ\n");
    253  1.1  mrg               exit (1);
    254  1.1  mrg             }
    255  1.1  mrg           else if (inexact && (mpfr_cmp (c, d) == 0))
    256  1.1  mrg             {
    257  1.1  mrg               printf ("inexact!=0 but results agree\n");
    258  1.1  mrg               printf ("prec=%u rnd=%s a=", (unsigned int) prec,
    259  1.1  mrg                       mpfr_print_rnd_mode (rnd));
    260  1.1  mrg               mpfr_out_str (stdout, 2, 0, a, rnd);
    261  1.1  mrg               printf ("\nb=");
    262  1.1  mrg               mpfr_out_str (stdout, 2, 0, b, rnd);
    263  1.1  mrg               printf ("\nc=");
    264  1.1  mrg               mpfr_out_str (stdout, 2, 0, c, rnd);
    265  1.1  mrg               printf ("\nd=");
    266  1.1  mrg               mpfr_out_str (stdout, 2, 0, d, rnd);
    267  1.1  mrg               printf ("\n");
    268  1.1  mrg               exit (1);
    269  1.1  mrg             }
    270  1.1  mrg         }
    271  1.1  mrg     }
    272  1.1  mrg 
    273  1.1  mrg   mpfr_clear (a);
    274  1.1  mrg   mpfr_clear (b);
    275  1.1  mrg   mpfr_clear (c);
    276  1.1  mrg   mpfr_clear (d);
    277  1.1  mrg }
    278  1.1  mrg 
    279  1.1  mrg static void
    280  1.1  mrg check_max(void)
    281  1.1  mrg {
    282  1.1  mrg   mpfr_t xx, yy, zz;
    283  1.1  mrg   mpfr_exp_t emin;
    284  1.1  mrg 
    285  1.1  mrg   mpfr_init2(xx, 4);
    286  1.1  mrg   mpfr_init2(yy, 4);
    287  1.1  mrg   mpfr_init2(zz, 4);
    288  1.1  mrg   mpfr_set_str1 (xx, "0.68750");
    289  1.1  mrg   mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, MPFR_RNDN);
    290  1.1  mrg   mpfr_set_str1 (yy, "0.68750");
    291  1.1  mrg   mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, MPFR_RNDN);
    292  1.1  mrg   mpfr_clear_flags();
    293  1.1  mrg   test_mul(zz, xx, yy, MPFR_RNDU);
    294  1.1  mrg   if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
    295  1.1  mrg     {
    296  1.1  mrg       printf("check_max failed (should be an overflow)\n");
    297  1.1  mrg       exit(1);
    298  1.1  mrg     }
    299  1.1  mrg 
    300  1.1  mrg   mpfr_clear_flags();
    301  1.1  mrg   test_mul(zz, xx, yy, MPFR_RNDD);
    302  1.1  mrg   if (mpfr_overflow_p() || MPFR_IS_INF(zz))
    303  1.1  mrg     {
    304  1.1  mrg       printf("check_max failed (should NOT be an overflow)\n");
    305  1.1  mrg       exit(1);
    306  1.1  mrg     }
    307  1.1  mrg   mpfr_set_str1 (xx, "0.93750");
    308  1.1  mrg   mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, MPFR_RNDN);
    309  1.1  mrg   if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
    310  1.1  mrg     {
    311  1.1  mrg       printf("check_max failed (internal error)\n");
    312  1.1  mrg       exit(1);
    313  1.1  mrg     }
    314  1.1  mrg   if (mpfr_cmp(xx, zz) != 0)
    315  1.1  mrg     {
    316  1.1  mrg       printf("check_max failed: got ");
    317  1.1  mrg       mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
    318  1.1  mrg       printf(" instead of ");
    319  1.1  mrg       mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
    320  1.1  mrg       printf("\n");
    321  1.1  mrg       exit(1);
    322  1.1  mrg     }
    323  1.1  mrg 
    324  1.1  mrg   /* check underflow */
    325  1.1  mrg   emin = mpfr_get_emin ();
    326  1.1  mrg   set_emin (0);
    327  1.1  mrg   mpfr_set_str_binary (xx, "0.1E0");
    328  1.1  mrg   mpfr_set_str_binary (yy, "0.1E0");
    329  1.1  mrg   test_mul (zz, xx, yy, MPFR_RNDN);
    330  1.1  mrg   /* exact result is 0.1E-1, which should round to 0 */
    331  1.1  mrg   MPFR_ASSERTN(mpfr_cmp_ui (zz, 0) == 0 && MPFR_IS_POS(zz));
    332  1.1  mrg   set_emin (emin);
    333  1.1  mrg 
    334  1.1  mrg   /* coverage test for mpfr_powerof2_raw */
    335  1.1  mrg   emin = mpfr_get_emin ();
    336  1.1  mrg   set_emin (0);
    337  1.1  mrg   mpfr_set_prec (xx, mp_bits_per_limb + 1);
    338  1.1  mrg   mpfr_set_str_binary (xx, "0.1E0");
    339  1.1  mrg   mpfr_nextabove (xx);
    340  1.1  mrg   mpfr_set_str_binary (yy, "0.1E0");
    341  1.1  mrg   test_mul (zz, xx, yy, MPFR_RNDN);
    342  1.1  mrg   /* exact result is just above 0.1E-1, which should round to minfloat */
    343  1.1  mrg   MPFR_ASSERTN(mpfr_cmp (zz, yy) == 0);
    344  1.1  mrg   set_emin (emin);
    345  1.1  mrg 
    346  1.1  mrg   mpfr_clear(xx);
    347  1.1  mrg   mpfr_clear(yy);
    348  1.1  mrg   mpfr_clear(zz);
    349  1.1  mrg }
    350  1.1  mrg 
    351  1.1  mrg static void
    352  1.1  mrg check_min(void)
    353  1.1  mrg {
    354  1.1  mrg   mpfr_t xx, yy, zz;
    355  1.1  mrg 
    356  1.1  mrg   mpfr_init2(xx, 4);
    357  1.1  mrg   mpfr_init2(yy, 4);
    358  1.1  mrg   mpfr_init2(zz, 3);
    359  1.1  mrg   mpfr_set_str1(xx, "0.9375");
    360  1.1  mrg   mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, MPFR_RNDN);
    361  1.1  mrg   mpfr_set_str1(yy, "0.9375");
    362  1.1  mrg   mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, MPFR_RNDN);
    363  1.1  mrg   test_mul(zz, xx, yy, MPFR_RNDD);
    364  1.1  mrg   if (mpfr_sgn(zz) != 0)
    365  1.1  mrg     {
    366  1.1  mrg       printf("check_min failed: got ");
    367  1.1  mrg       mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
    368  1.1  mrg       printf(" instead of 0\n");
    369  1.1  mrg       exit(1);
    370  1.1  mrg     }
    371  1.1  mrg 
    372  1.1  mrg   test_mul(zz, xx, yy, MPFR_RNDU);
    373  1.1  mrg   mpfr_set_str1 (xx, "0.5");
    374  1.1  mrg   mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, MPFR_RNDN);
    375  1.1  mrg   if (mpfr_sgn(xx) <= 0)
    376  1.1  mrg     {
    377  1.1  mrg       printf("check_min failed (internal error)\n");
    378  1.1  mrg       exit(1);
    379  1.1  mrg     }
    380  1.1  mrg   if (mpfr_cmp(xx, zz) != 0)
    381  1.1  mrg     {
    382  1.1  mrg       printf("check_min failed: got ");
    383  1.1  mrg       mpfr_out_str(stdout, 2, 0, zz, MPFR_RNDZ);
    384  1.1  mrg       printf(" instead of ");
    385  1.1  mrg       mpfr_out_str(stdout, 2, 0, xx, MPFR_RNDZ);
    386  1.1  mrg       printf("\n");
    387  1.1  mrg       exit(1);
    388  1.1  mrg     }
    389  1.1  mrg 
    390  1.1  mrg   mpfr_clear(xx);
    391  1.1  mrg   mpfr_clear(yy);
    392  1.1  mrg   mpfr_clear(zz);
    393  1.1  mrg }
    394  1.1  mrg 
    395  1.1  mrg static void
    396  1.1  mrg check_nans (void)
    397  1.1  mrg {
    398  1.1  mrg   mpfr_t  p, x, y;
    399  1.1  mrg 
    400  1.1  mrg   mpfr_init2 (x, 123L);
    401  1.1  mrg   mpfr_init2 (y, 123L);
    402  1.1  mrg   mpfr_init2 (p, 123L);
    403  1.1  mrg 
    404  1.1  mrg   /* nan * 0 == nan */
    405  1.1  mrg   mpfr_set_nan (x);
    406  1.1  mrg   mpfr_set_ui (y, 0L, MPFR_RNDN);
    407  1.1  mrg   test_mul (p, x, y, MPFR_RNDN);
    408  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (p));
    409  1.1  mrg 
    410  1.1  mrg   /* 1 * nan == nan */
    411  1.1  mrg   mpfr_set_ui (x, 1L, MPFR_RNDN);
    412  1.1  mrg   mpfr_set_nan (y);
    413  1.1  mrg   test_mul (p, x, y, MPFR_RNDN);
    414  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (p));
    415  1.1  mrg 
    416  1.1  mrg   /* 0 * +inf == nan */
    417  1.1  mrg   mpfr_set_ui (x, 0L, MPFR_RNDN);
    418  1.1  mrg   mpfr_set_nan (y);
    419  1.1  mrg   test_mul (p, x, y, MPFR_RNDN);
    420  1.1  mrg   MPFR_ASSERTN (mpfr_nan_p (p));
    421  1.1  mrg 
    422  1.1  mrg   /* +1 * +inf == +inf */
    423  1.1  mrg   mpfr_set_ui (x, 1L, MPFR_RNDN);
    424  1.1  mrg   mpfr_set_inf (y, 1);
    425  1.1  mrg   test_mul (p, x, y, MPFR_RNDN);
    426  1.1  mrg   MPFR_ASSERTN (mpfr_inf_p (p));
    427  1.1  mrg   MPFR_ASSERTN (mpfr_sgn (p) > 0);
    428  1.1  mrg 
    429  1.1  mrg   /* -1 * +inf == -inf */
    430  1.1  mrg   mpfr_set_si (x, -1L, MPFR_RNDN);
    431  1.1  mrg   mpfr_set_inf (y, 1);
    432  1.1  mrg   test_mul (p, x, y, MPFR_RNDN);
    433  1.1  mrg   MPFR_ASSERTN (mpfr_inf_p (p));
    434  1.1  mrg   MPFR_ASSERTN (mpfr_sgn (p) < 0);
    435  1.1  mrg 
    436  1.1  mrg   mpfr_clear (x);
    437  1.1  mrg   mpfr_clear (y);
    438  1.1  mrg   mpfr_clear (p);
    439  1.1  mrg }
    440  1.1  mrg 
    441  1.1  mrg #define BUFSIZE 1552
    442  1.1  mrg 
    443  1.1  mrg static void
    444  1.1  mrg get_string (char *s, FILE *fp)
    445  1.1  mrg {
    446  1.1  mrg   int c, n = BUFSIZE;
    447  1.1  mrg 
    448  1.1  mrg   while ((c = getc (fp)) != '\n')
    449  1.1  mrg     {
    450  1.1  mrg       if (c == EOF)
    451  1.1  mrg         {
    452  1.1  mrg           printf ("Error in get_string: end of file\n");
    453  1.1  mrg           exit (1);
    454  1.1  mrg         }
    455  1.1  mrg       *(unsigned char *)s++ = c;
    456  1.1  mrg       if (--n == 0)
    457  1.1  mrg         {
    458  1.1  mrg           printf ("Error in get_string: buffer is too small\n");
    459  1.1  mrg           exit (1);
    460  1.1  mrg         }
    461  1.1  mrg     }
    462  1.1  mrg   *s = '\0';
    463  1.1  mrg }
    464  1.1  mrg 
    465  1.1  mrg static void
    466  1.1  mrg check_regression (void)
    467  1.1  mrg {
    468  1.1  mrg   mpfr_t x, y, z;
    469  1.1  mrg   int i;
    470  1.1  mrg   FILE *fp;
    471  1.1  mrg   char s[BUFSIZE];
    472  1.1  mrg 
    473  1.1  mrg   mpfr_inits2 (6177, x, y, z, (mpfr_ptr) 0);
    474  1.1  mrg   /* we read long strings from a file since ISO C90 does not support strings of
    475  1.1  mrg      length > 509 */
    476  1.1  mrg   fp = src_fopen ("tmul.dat", "r");
    477  1.1  mrg   if (fp == NULL)
    478  1.1  mrg     {
    479  1.1  mrg       fprintf (stderr, "Error, cannot open tmul.dat in srcdir\n");
    480  1.1  mrg       exit (1);
    481  1.1  mrg     }
    482  1.1  mrg   get_string (s, fp);
    483  1.1  mrg   mpfr_set_str (y, s, 16, MPFR_RNDN);
    484  1.1  mrg   get_string (s, fp);
    485  1.1  mrg   mpfr_set_str (z, s, 16, MPFR_RNDN);
    486  1.1  mrg   i = mpfr_mul (x, y, z, MPFR_RNDN);
    487  1.1  mrg   get_string (s, fp);
    488  1.1  mrg   if (mpfr_cmp_str (x, s, 16, MPFR_RNDN) != 0 || i != -1)
    489  1.1  mrg     {
    490  1.1  mrg       printf ("Regression test 1 failed (i=%d, expected -1)\nx=", i);
    491  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
    492  1.1  mrg       exit (1);
    493  1.1  mrg     }
    494  1.1  mrg   fclose (fp);
    495  1.1  mrg 
    496  1.1  mrg   mpfr_set_prec (x, 606);
    497  1.1  mrg   mpfr_set_prec (y, 606);
    498  1.1  mrg   mpfr_set_prec (z, 606);
    499  1.1  mrg 
    500  1.1  mrg   mpfr_set_str (y, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
    501  1.1  mrg   mpfr_set_str (z, "-f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92daefc3f8052ca9f58736564d9e93e62d324@-1", 16, MPFR_RNDN);
    502  1.1  mrg   i = mpfr_mul (x, y, z, MPFR_RNDU);
    503  1.1  mrg   mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25b5df87f00a5953eb0e6cac9b3d27cc5a64c@-1", 16, MPFR_RNDN);
    504  1.1  mrg   if (mpfr_cmp (x, y) || i <= 0)
    505  1.1  mrg     {
    506  1.1  mrg       printf ("Regression test (2) failed! (i=%d - Expected 1)\n", i);
    507  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
    508  1.1  mrg       exit (1);
    509  1.1  mrg     }
    510  1.1  mrg 
    511  1.1  mrg   mpfr_set_prec (x, 184);
    512  1.1  mrg   mpfr_set_prec (y, 92);
    513  1.1  mrg   mpfr_set_prec (z, 1023);
    514  1.1  mrg 
    515  1.1  mrg   mpfr_set_str (y, "6.9b8c8498882770d8038c3b0@-1", 16, MPFR_RNDN);
    516  1.1  mrg   mpfr_set_str (z, "7.44e24b986e7fb296f1e936ce749fec3504cbf0d5ba769466b1c9f1578115efd5d29b4c79271191a920a99280c714d3a657ad6e3afbab77ffce9d697e9bb9110e26d676069afcea8b69f1d1541f2365042d80a97c21dcccd8ace4f1bb58b49922003e738e6f37bb82ef653cb2e87f763974e6ae50ae54e7724c38b80653e3289@255", 16, MPFR_RNDN);
    517  1.1  mrg   i = mpfr_mul (x, y, z, MPFR_RNDU);
    518  1.1  mrg   mpfr_set_prec (y, 184);
    519  1.1  mrg   mpfr_set_str (y, "3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255",
    520  1.1  mrg                 16, MPFR_RNDN);
    521  1.1  mrg   if (mpfr_cmp (x, y) || i <= 0)
    522  1.1  mrg     {
    523  1.1  mrg       printf ("Regression test (4) failed! (i=%d - expected 1)\n", i);
    524  1.1  mrg       printf ("Ref: 3.0080038f2ac5054e3e71ccbb95f76aaab2221715025a28@255\n"
    525  1.1  mrg               "Got: ");
    526  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
    527  1.1  mrg       printf ("\n");
    528  1.1  mrg       exit (1);
    529  1.1  mrg     }
    530  1.1  mrg 
    531  1.1  mrg   mpfr_set_prec (x, 908);
    532  1.1  mrg   mpfr_set_prec (y, 908);
    533  1.1  mrg   mpfr_set_prec (z, 908);
    534  1.1  mrg   mpfr_set_str (y, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    535  1.1  mrg "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    536  1.1  mrg "ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
    537  1.1  mrg "e6e9a327230345ea6@-1", 16, MPFR_RNDN);
    538  1.1  mrg   mpfr_set_str (z, "-f.fffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    539  1.1  mrg "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    540  1.1  mrg "ffffffffffffffffffffffffffffffffffffffffffffffffffffff99be91f83ec6f0ed28a3d42"
    541  1.1  mrg                 "e6e9a327230345ea6@-1", 16, MPFR_RNDN);
    542  1.1  mrg   i = mpfr_mul (x, y, z, MPFR_RNDU);
    543  1.1  mrg   mpfr_set_str (y, "f.ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    544  1.1  mrg "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
    545  1.1  mrg "fffffffffffffffffffffffffffffffffffffffffffffffffffff337d23f07d8de1da5147a85c"
    546  1.1  mrg "dd3464e46068bd4d@-1", 16, MPFR_RNDN);
    547  1.1  mrg   if (mpfr_cmp (x, y) || i <= 0)
    548  1.1  mrg     {
    549  1.1  mrg       printf ("Regression test (5) failed! (i=%d - expected 1)\n", i);
    550  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
    551  1.1  mrg       printf ("\n");
    552  1.1  mrg       exit (1);
    553  1.1  mrg     }
    554  1.1  mrg 
    555  1.1  mrg 
    556  1.1  mrg   mpfr_set_prec (x, 50);
    557  1.1  mrg   mpfr_set_prec (y, 40);
    558  1.1  mrg   mpfr_set_prec (z, 53);
    559  1.1  mrg   mpfr_set_str (y, "4.1ffffffff8", 16, MPFR_RNDN);
    560  1.1  mrg   mpfr_set_str (z, "4.2000000ffe0000@-4", 16, MPFR_RNDN);
    561  1.1  mrg   i = mpfr_mul (x, y, z, MPFR_RNDN);
    562  1.1  mrg   if (mpfr_cmp_str (x, "1.104000041d6c0@-3", 16, MPFR_RNDN) != 0
    563  1.1  mrg       || i <= 0)
    564  1.1  mrg     {
    565  1.1  mrg       printf ("Regression test (6) failed! (i=%d - expected 1)\nx=", i);
    566  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
    567  1.1  mrg       printf ("\nMore prec=");
    568  1.1  mrg       mpfr_set_prec (x, 93);
    569  1.1  mrg       mpfr_mul (x, y, z, MPFR_RNDN);
    570  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
    571  1.1  mrg       printf ("\n");
    572  1.1  mrg       exit (1);
    573  1.1  mrg     }
    574  1.1  mrg 
    575  1.1  mrg   mpfr_set_prec (x, 439);
    576  1.1  mrg   mpfr_set_prec (y, 393);
    577  1.1  mrg   mpfr_set_str (y, "-1.921fb54442d18469898cc51701b839a252049c1114cf98e804177d"
    578  1.1  mrg                 "4c76273644a29410f31c6809bbdf2a33679a748636600",
    579  1.1  mrg                 16, MPFR_RNDN);
    580  1.1  mrg   i = mpfr_mul (x, y, y, MPFR_RNDU);
    581  1.1  mrg   if (mpfr_cmp_str (x, "2.77a79937c8bbcb495b89b36602306b1c2159a8ff834288a19a08"
    582  1.1  mrg     "84094f1cda3dc426da61174c4544a173de83c2500f8bfea2e0569e3698",
    583  1.1  mrg                     16, MPFR_RNDN) != 0
    584  1.1  mrg       || i <= 0)
    585  1.1  mrg     {
    586  1.1  mrg       printf ("Regression test (7) failed! (i=%d - expected 1)\nx=", i);
    587  1.1  mrg       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
    588  1.1  mrg       printf ("\n");
    589  1.1  mrg       exit (1);
    590  1.1  mrg     }
    591  1.1  mrg 
    592  1.1  mrg   mpfr_set_prec (x, 1023);
    593  1.1  mrg   mpfr_set_prec (y, 1023);
    594  1.1  mrg   mpfr_set_prec (z, 511);
    595  1.1  mrg   mpfr_set_ui (x, 17, MPFR_RNDN);
    596  1.1  mrg   mpfr_set_ui (y, 42, MPFR_RNDN);
    597  1.1  mrg   i = mpfr_mul (z, x, y, MPFR_RNDN);
    598  1.1  mrg   if (mpfr_cmp_ui (z, 17*42) != 0 || i != 0)
    599  1.1  mrg     {
    600  1.1  mrg       printf ("Regression test (8) failed! (i=%d - expected 0)\nz=", i);
    601  1.1  mrg       mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
    602  1.1  mrg       printf ("\n");
    603  1.1  mrg       exit (1);
    604  1.1  mrg     }
    605  1.1  mrg 
    606  1.1  mrg   mpfr_clears (x, y, z, (mpfr_ptr) 0);
    607  1.1  mrg }
    608  1.1  mrg 
    609  1.1  mrg #define TEST_FUNCTION test_mul
    610  1.1  mrg #define TWO_ARGS
    611  1.1  mrg #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
    612  1.1  mrg #include "tgeneric.c"
    613  1.1  mrg 
    614  1.1  mrg /* multiplies x by 53-bit approximation of Pi */
    615  1.1  mrg static int
    616  1.1  mrg mpfr_mulpi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
    617  1.1  mrg {
    618  1.1  mrg   mpfr_t z;
    619  1.1  mrg   int inex;
    620  1.1  mrg 
    621  1.1  mrg   mpfr_init2 (z, 53);
    622  1.1  mrg   mpfr_set_str_binary (z, "11.001001000011111101101010100010001000010110100011");
    623  1.1  mrg   inex = mpfr_mul (y, x, z, r);
    624  1.1  mrg   mpfr_clear (z);
    625  1.1  mrg   return inex;
    626  1.1  mrg }
    627  1.1  mrg 
    628  1.1  mrg int
    629  1.1  mrg main (int argc, char *argv[])
    630  1.1  mrg {
    631  1.1  mrg   tests_start_mpfr ();
    632  1.1  mrg 
    633  1.1  mrg   check_nans ();
    634  1.1  mrg   check_exact ();
    635  1.1  mrg   check_float ();
    636  1.1  mrg 
    637  1.1  mrg   check53("6.9314718055994530941514e-1", "0.0", MPFR_RNDZ, "0.0");
    638  1.1  mrg   check53("0.0", "6.9314718055994530941514e-1", MPFR_RNDZ, "0.0");
    639  1.1  mrg   check_sign();
    640  1.1  mrg   check53("-4.165000000e4", "-0.00004801920768307322868063274915", MPFR_RNDN,
    641  1.1  mrg           "2.0");
    642  1.1  mrg   check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
    643  1.1  mrg           MPFR_RNDZ, "-1.8251348697787782844e-172");
    644  1.1  mrg   check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
    645  1.1  mrg           MPFR_RNDA, "-1.8251348697787786e-172");
    646  1.1  mrg   check53("0.31869277231188065", "0.88642843322303122", MPFR_RNDZ,
    647  1.1  mrg           "2.8249833483992453642e-1");
    648  1.1  mrg   check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDU,
    649  1.1  mrg         28, 45, 2, "0.375");
    650  1.1  mrg   check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDA,
    651  1.1  mrg         28, 45, 2, "0.375");
    652  1.1  mrg   check("2.63978122803639081440e-01", "6.8378615379333496093e-1", MPFR_RNDN,
    653  1.1  mrg         34, 23, 31, "0.180504585267044603");
    654  1.1  mrg   check("1.0", "0.11835170935876249132", MPFR_RNDU, 6, 41, 36,
    655  1.1  mrg         "0.1183517093595583");
    656  1.1  mrg   check53("67108865.0", "134217729.0", MPFR_RNDN, "9.007199456067584e15");
    657  1.1  mrg   check("1.37399642157394197284e-01", "2.28877275604219221350e-01", MPFR_RNDN,
    658  1.1  mrg         49, 15, 32, "0.0314472340833162888");
    659  1.1  mrg   check("4.03160720978664954828e-01", "5.854828e-1"
    660  1.1  mrg         /*"5.85483042917246621073e-01"*/, MPFR_RNDZ,
    661  1.1  mrg         51, 22, 32, "0.2360436821472831");
    662  1.1  mrg   check("3.90798504668055102229e-14", "9.85394674650308388664e-04", MPFR_RNDN,
    663  1.1  mrg         46, 22, 12, "0.385027296503914762e-16");
    664  1.1  mrg   check("4.58687081072827851358e-01", "2.20543551472118792844e-01", MPFR_RNDN,
    665  1.1  mrg         49, 3, 2, "0.09375");
    666  1.1  mrg   check_max();
    667  1.1  mrg   check_min();
    668  1.1  mrg 
    669  1.1  mrg   check_regression ();
    670  1.1  mrg   test_generic (2, 500, 100);
    671  1.1  mrg 
    672  1.1  mrg   data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi");
    673  1.1  mrg 
    674  1.1  mrg   tests_end_mpfr ();
    675  1.1  mrg   return 0;
    676  1.1  mrg }
    677