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