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