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