xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tmul.c (revision fa28c6faa16e0b00edee7acdcaf4899797043def)
1 /* Test file for mpfr_mul.
2 
3 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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_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 */
54 static void
55 check (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 
88 static void
89 check53 (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 */
120 static void
121 check24 (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 */
143 static void
144 check_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 */
188 static void
189 check_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 */
209 static void
210 check_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 
279 static void
280 check_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 
351 static void
352 check_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 
395 static void
396 check_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 
443 static void
444 get_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 
465 static void
466 check_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 */
615 static int
616 mpfr_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 
628 static void
629 valgrind20110503 (void)
630 {
631   mpfr_t a, b, c;
632 
633   mpfr_init2 (a, 2);
634   mpfr_init2 (b, 2005);
635   mpfr_init2 (c, 2);
636 
637   mpfr_set_ui (b, 5, MPFR_RNDN);
638   mpfr_nextabove (b);
639   mpfr_set_ui (c, 1, MPFR_RNDN);
640   mpfr_mul (a, b, c, MPFR_RNDZ);
641   /* After the call to mpfr_mulhigh_n, valgrind complains:
642      Conditional jump or move depends on uninitialised value(s) */
643 
644   mpfr_clears (a, b, c, (mpfr_ptr) 0);
645 }
646 
647 int
648 main (int argc, char *argv[])
649 {
650   tests_start_mpfr ();
651 
652   check_nans ();
653   check_exact ();
654   check_float ();
655 
656   check53("6.9314718055994530941514e-1", "0.0", MPFR_RNDZ, "0.0");
657   check53("0.0", "6.9314718055994530941514e-1", MPFR_RNDZ, "0.0");
658   check_sign();
659   check53("-4.165000000e4", "-0.00004801920768307322868063274915", MPFR_RNDN,
660           "2.0");
661   check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
662           MPFR_RNDZ, "-1.8251348697787782844e-172");
663   check53("2.71331408349172961467e-08", "-6.72658901114033715233e-165",
664           MPFR_RNDA, "-1.8251348697787786e-172");
665   check53("0.31869277231188065", "0.88642843322303122", MPFR_RNDZ,
666           "2.8249833483992453642e-1");
667   check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDU,
668         28, 45, 2, "0.375");
669   check("8.47622108205396074254e-01", "3.24039313247872939883e-01", MPFR_RNDA,
670         28, 45, 2, "0.375");
671   check("2.63978122803639081440e-01", "6.8378615379333496093e-1", MPFR_RNDN,
672         34, 23, 31, "0.180504585267044603");
673   check("1.0", "0.11835170935876249132", MPFR_RNDU, 6, 41, 36,
674         "0.1183517093595583");
675   check53("67108865.0", "134217729.0", MPFR_RNDN, "9.007199456067584e15");
676   check("1.37399642157394197284e-01", "2.28877275604219221350e-01", MPFR_RNDN,
677         49, 15, 32, "0.0314472340833162888");
678   check("4.03160720978664954828e-01", "5.854828e-1"
679         /*"5.85483042917246621073e-01"*/, MPFR_RNDZ,
680         51, 22, 32, "0.2360436821472831");
681   check("3.90798504668055102229e-14", "9.85394674650308388664e-04", MPFR_RNDN,
682         46, 22, 12, "0.385027296503914762e-16");
683   check("4.58687081072827851358e-01", "2.20543551472118792844e-01", MPFR_RNDN,
684         49, 3, 2, "0.09375");
685   check_max();
686   check_min();
687 
688   check_regression ();
689   test_generic (2, 500, 100);
690 
691   data_check ("data/mulpi", mpfr_mulpi, "mpfr_mulpi");
692 
693   valgrind20110503 ();
694 
695   tests_end_mpfr ();
696   return 0;
697 }
698