Annotation of OpenXM_contrib/gmp/mpfr/tests/tmul.c, Revision 1.1.1.1
1.1 ohara 1: /* Test file for mpfr_mul.
2:
3: Copyright 1999, 2001, 2002 Free Software Foundation, Inc.
4:
5: This file is part of the MPFR Library.
6:
7: The MPFR Library is free software; you can redistribute it and/or modify
8: it under the terms of the GNU Lesser General Public License as published by
9: the Free Software Foundation; either version 2.1 of the License, or (at your
10: option) any later version.
11:
12: The MPFR Library is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15: License for more details.
16:
17: You should have received a copy of the GNU Lesser General Public License
18: along with the MPFR Library; see the file COPYING.LIB. If not, write to
19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20: MA 02111-1307, USA. */
21:
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <time.h>
25: #include "gmp.h"
26: #include "gmp-impl.h"
27: #include "mpfr.h"
28: #include "mpfr-impl.h"
29: #include "mpfr-test.h"
30:
31: void check53 _PROTO((double, double, mp_rnd_t, double));
32: void check24 _PROTO((float, float, mp_rnd_t, float));
33: void check_float _PROTO((void));
34: void check_sign _PROTO((void));
35: void check_exact _PROTO((void));
36: void check_max _PROTO((void));
37: void check_min _PROTO((void));
38:
39:
40: /* Workaround for sparc gcc 2.95.x bug, see notes in tadd.c. */
41: #define check(x,y,rnd_mode,px,py,pz,res) _check(x,y,res,rnd_mode,px,py,pz)
42:
43: /* checks that x*y gives the same results in double
44: and with mpfr with 53 bits of precision */
45: void
46: _check (double x, double y, double res, mp_rnd_t rnd_mode, unsigned int px,
47: unsigned int py, unsigned int pz)
48: {
49: double z1, z2; mpfr_t xx, yy, zz;
50:
51: mpfr_init2 (xx, px);
52: mpfr_init2 (yy, py);
53: mpfr_init2 (zz, pz);
54: mpfr_set_d(xx, x, rnd_mode);
55: mpfr_set_d(yy, y, rnd_mode);
56: mpfr_mul(zz, xx, yy, rnd_mode);
57: #ifdef MPFR_HAVE_FESETROUND
58: mpfr_set_machine_rnd_mode(rnd_mode);
59: #endif
60: z1 = (res==0.0) ? x*y : res;
61: z2 = mpfr_get_d1 (zz);
62: if (z1!=z2 && (z1>=MINNORM || z1<=-MINNORM)) {
63: printf("mpfr_mul ");
64: if (res==0.0) printf("differs from libm.a"); else printf("failed");
65: printf(" for x=%1.20e y=%1.20e with rnd_mode=%s\n", x, y,
66: mpfr_print_rnd_mode(rnd_mode));
67: printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
68: if (res!=0.0) exit(1);
69: }
70: mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
71: }
72:
73: void
74: check53 (double x, double y, mp_rnd_t rnd_mode, double z1)
75: {
76: double z2; mpfr_t xx, yy, zz;
77:
78: mpfr_init2 (xx, 53);
79: mpfr_init2 (yy, 53);
80: mpfr_init2 (zz, 53);
81: mpfr_set_d (xx, x, rnd_mode);
82: mpfr_set_d (yy, y, rnd_mode);
83: mpfr_mul (zz, xx, yy, rnd_mode);
84: z2 = mpfr_get_d1 (zz);
85: if (z1!=z2 && (!isnan(z1) || !isnan(z2))) {
86: printf("mpfr_mul failed for x=%1.20e y=%1.20e with rnd_mode=%s\n",
87: x, y, mpfr_print_rnd_mode(rnd_mode));
88: printf("libm.a gives %1.20e, mpfr_mul gives %1.20e\n", z1, z2);
89: exit(1);
90: }
91: mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
92: }
93:
94: /* checks that x*y gives the same results in double
95: and with mpfr with 24 bits of precision */
96: void
97: check24 (float x, float y, mp_rnd_t rnd_mode, float z1)
98: {
99: float z2;
100: mpfr_t xx, yy, zz;
101:
102: mpfr_init2 (xx, 24);
103: mpfr_init2 (yy, 24);
104: mpfr_init2 (zz, 24);
105: mpfr_set_d (xx, x, rnd_mode);
106: mpfr_set_d (yy, y, rnd_mode);
107: mpfr_mul (zz, xx, yy, rnd_mode);
108: z2 = (float) mpfr_get_d1 (zz);
109: if (z1 != z2)
110: {
111: fprintf (stderr, "mpfr_mul failed for x=%1.0f y=%1.0f with prec=24 and"
112: "rnd=%s\n", x, y, mpfr_print_rnd_mode(rnd_mode));
113: fprintf (stderr, "libm.a gives %.10e, mpfr_mul gives %.10e\n", z1, z2);
114: exit (1);
115: }
116: mpfr_clear(xx);
117: mpfr_clear(yy);
118: mpfr_clear(zz);
119: }
120:
121: /* the following examples come from the paper "Number-theoretic Test
122: Generation for Directed Rounding" from Michael Parks, Table 1 */
123: void
124: check_float (void)
125: {
126: float z;
127:
128: check24(8388609.0, 8388609.0, GMP_RNDN, 70368760954880.0);
129: check24(16777213.0, 8388609.0, GMP_RNDN, 140737479966720.0);
130: check24(8388611.0, 8388609.0, GMP_RNDN, 70368777732096.0);
131: check24(12582911.0, 8388610.0, GMP_RNDN, 105553133043712.0);
132: check24(12582914.0, 8388610.0, GMP_RNDN, 105553158209536.0);
133: check24(13981013.0, 8388611.0, GMP_RNDN, 117281279442944.0);
134: check24(11184811.0, 8388611.0, GMP_RNDN, 93825028587520.0);
135: check24(11184810.0, 8388611.0, GMP_RNDN, 93825020198912.0);
136: check24(13981014.0, 8388611.0, GMP_RNDN, 117281287831552.0);
137:
138: check24(8388609.0, 8388609.0, GMP_RNDZ, 70368760954880.0);
139: check24(16777213.0, 8388609.0, GMP_RNDZ, 140737471578112.0);
140: z = 70368777732096.0;
141: check24(8388611.0, 8388609.0, GMP_RNDZ, z);
142: check24(12582911.0, 8388610.0, GMP_RNDZ, 105553124655104.0);
143: check24(12582914.0, 8388610.0, GMP_RNDZ, 105553158209536.0);
144: check24(13981013.0, 8388611.0, GMP_RNDZ, 117281271054336.0);
145: check24(11184811.0, 8388611.0, GMP_RNDZ, 93825028587520.0);
146: check24(11184810.0, 8388611.0, GMP_RNDZ, 93825011810304.0);
147: check24(13981014.0, 8388611.0, GMP_RNDZ, 117281287831552.0);
148:
149: check24(8388609.0, 8388609.0, GMP_RNDU, 70368769343488.0);
150: check24(16777213.0, 8388609.0, GMP_RNDU, 140737479966720.0);
151: check24(8388611.0, 8388609.0, GMP_RNDU, 70368786120704.0);
152: check24(12582911.0, 8388610.0, GMP_RNDU, 105553133043712.0);
153: check24(12582914.0, 8388610.0, GMP_RNDU, 105553166598144.0);
154: check24(13981013.0, 8388611.0, GMP_RNDU, 117281279442944.0);
155: check24(11184811.0, 8388611.0, GMP_RNDU, 93825036976128.0);
156: check24(11184810.0, 8388611.0, GMP_RNDU, 93825020198912.0);
157: check24(13981014.0, 8388611.0, GMP_RNDU, 117281296220160.0);
158:
159: check24(8388609.0, 8388609.0, GMP_RNDD, 70368760954880.0);
160: check24(16777213.0, 8388609.0, GMP_RNDD, 140737471578112.0);
161: check24(8388611.0, 8388609.0, GMP_RNDD, 70368777732096.0);
162: check24(12582911.0, 8388610.0, GMP_RNDD, 105553124655104.0);
163: check24(12582914.0, 8388610.0, GMP_RNDD, 105553158209536.0);
164: check24(13981013.0, 8388611.0, GMP_RNDD, 117281271054336.0);
165: check24(11184811.0, 8388611.0, GMP_RNDD, 93825028587520.0);
166: check24(11184810.0, 8388611.0, GMP_RNDD, 93825011810304.0);
167: check24(13981014.0, 8388611.0, GMP_RNDD, 117281287831552.0);
168: }
169:
170: /* check sign of result */
171: void
172: check_sign (void)
173: {
174: mpfr_t a, b;
175:
176: mpfr_init2 (a, 53);
177: mpfr_init2 (b, 53);
178: mpfr_set_d(a, -1.0, GMP_RNDN);
179: mpfr_set_d(b, 2.0, GMP_RNDN);
180: mpfr_mul(a, b, b, GMP_RNDN);
181: if (mpfr_get_d1 (a) != 4.0) {
182: fprintf(stderr,"2.0*2.0 gives %1.20e\n", mpfr_get_d1 (a)); exit(1);
183: }
184: mpfr_clear(a); mpfr_clear(b);
185: }
186:
187: /* checks that the inexact return value is correct */
188: void
189: check_exact (void)
190: {
191: mpfr_t a, b, c, d;
192: mp_prec_t prec;
193: int i, inexact;
194: mp_rnd_t rnd;
195:
196: mpfr_init (a);
197: mpfr_init (b);
198: mpfr_init (c);
199: mpfr_init (d);
200:
201: mpfr_set_prec (a, 17);
202: mpfr_set_prec (b, 17);
203: mpfr_set_prec (c, 32);
204: mpfr_set_str_raw (a, "1.1000111011000100e-1");
205: mpfr_set_str_raw (b, "1.0010001111100111e-1");
206: if (mpfr_mul (c, a, b, GMP_RNDZ))
207: {
208: fprintf (stderr, "wrong return value (1)\n");
209: exit (1);
210: }
211:
212: for (prec = 2; prec < 100; prec++)
213: {
214: mpfr_set_prec (a, prec);
215: mpfr_set_prec (b, prec);
216: mpfr_set_prec (c, 2 * prec - 2);
217: mpfr_set_prec (d, 2 * prec);
218: for (i = 0; i < 1000; i++)
219: {
220: mpfr_random (a);
221: mpfr_random (b);
222: rnd = LONG_RAND() % 4;
223: inexact = mpfr_mul (c, a, b, rnd);
224: if (mpfr_mul (d, a, b, rnd)) /* should be always exact */
225: {
226: fprintf (stderr, "unexpected inexact return value\n");
227: exit (1);
228: }
229: if ((inexact == 0) && mpfr_cmp (c, d))
230: {
231: fprintf (stderr, "inexact=0 but results differ\n");
232: exit (1);
233: }
234: else if (inexact && (mpfr_cmp (c, d) == 0))
235: {
236: fprintf (stderr, "inexact!=0 but results agree\n");
237: fprintf (stderr, "prec=%u rnd=%s a=", (unsigned int) prec,
238: mpfr_print_rnd_mode (rnd));
239: mpfr_out_str (stderr, 2, 0, a, rnd);
240: fprintf (stderr, "\nb=");
241: mpfr_out_str (stderr, 2, 0, b, rnd);
242: fprintf (stderr, "\nc=");
243: mpfr_out_str (stderr, 2, 0, c, rnd);
244: fprintf (stderr, "\nd=");
245: mpfr_out_str (stderr, 2, 0, d, rnd);
246: fprintf (stderr, "\n");
247: exit (1);
248: }
249: }
250: }
251:
252: mpfr_clear (a);
253: mpfr_clear (b);
254: mpfr_clear (c);
255: mpfr_clear (d);
256: }
257:
258: void
259: check_max(void)
260: {
261: mpfr_t xx, yy, zz;
262:
263: mpfr_init2(xx, 4);
264: mpfr_init2(yy, 4);
265: mpfr_init2(zz, 4);
266: mpfr_set_d(xx, 11.0/16, GMP_RNDN);
267: mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT/2, GMP_RNDN);
268: mpfr_set_d(yy, 11.0/16, GMP_RNDN);
269: mpfr_mul_2si(yy, yy, MPFR_EMAX_DEFAULT - MPFR_EMAX_DEFAULT/2 + 1, GMP_RNDN);
270: mpfr_clear_flags();
271: mpfr_mul(zz, xx, yy, GMP_RNDU);
272: if (!(mpfr_overflow_p() && MPFR_IS_INF(zz)))
273: {
274: printf("check_max failed (should be an overflow)\n");
275: exit(1);
276: }
277:
278: mpfr_clear_flags();
279: mpfr_mul(zz, xx, yy, GMP_RNDD);
280: if (mpfr_overflow_p() || MPFR_IS_INF(zz))
281: {
282: printf("check_max failed (should NOT be an overflow)\n");
283: exit(1);
284: }
285: mpfr_set_d(xx, 15.0/16, GMP_RNDN);
286: mpfr_mul_2si(xx, xx, MPFR_EMAX_DEFAULT, GMP_RNDN);
287: if (!(MPFR_IS_FP(xx) && MPFR_IS_FP(zz)))
288: {
289: printf("check_max failed (internal error)\n");
290: exit(1);
291: }
292: if (mpfr_cmp(xx, zz) != 0)
293: {
294: printf("check_max failed: got ");
295: mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
296: printf(" instead of ");
297: mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ);
298: printf("\n");
299: exit(1);
300: }
301:
302: mpfr_clear(xx);
303: mpfr_clear(yy);
304: mpfr_clear(zz);
305: }
306:
307: void
308: check_min(void)
309: {
310: mpfr_t xx, yy, zz;
311:
312: mpfr_init2(xx, 4);
313: mpfr_init2(yy, 4);
314: mpfr_init2(zz, 3);
315: mpfr_set_d(xx, 15.0/16, GMP_RNDN);
316: mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT/2, GMP_RNDN);
317: mpfr_set_d(yy, 15.0/16, GMP_RNDN);
318: mpfr_mul_2si(yy, yy, MPFR_EMIN_DEFAULT - MPFR_EMIN_DEFAULT/2 - 1, GMP_RNDN);
319: mpfr_mul(zz, xx, yy, GMP_RNDD);
320: if (mpfr_sgn(zz) != 0)
321: {
322: printf("check_min failed: got ");
323: mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
324: printf(" instead of 0\n");
325: exit(1);
326: }
327:
328: mpfr_mul(zz, xx, yy, GMP_RNDU);
329: mpfr_set_d(xx, 0.5, GMP_RNDN);
330: mpfr_mul_2si(xx, xx, MPFR_EMIN_DEFAULT, GMP_RNDN);
331: if (mpfr_sgn(xx) <= 0)
332: {
333: printf("check_min failed (internal error)\n");
334: exit(1);
335: }
336: if (mpfr_cmp(xx, zz) != 0)
337: {
338: printf("check_min failed: got ");
339: mpfr_out_str(stdout, 2, 0, zz, GMP_RNDZ);
340: printf(" instead of ");
341: mpfr_out_str(stdout, 2, 0, xx, GMP_RNDZ);
342: printf("\n");
343: exit(1);
344: }
345:
346: mpfr_clear(xx);
347: mpfr_clear(yy);
348: mpfr_clear(zz);
349: }
350:
351: int
352: main (int argc, char *argv[])
353: {
354: #ifdef MPFR_HAVE_FESETROUND
355: double x, y, z;
356: int i, prec, rnd_mode;
357:
358: mpfr_test_init ();
359: #endif
360:
361: check_exact ();
362: check_float ();
363: #ifdef HAVE_INFS
364: check53 (0.0, DBL_POS_INF, GMP_RNDN, DBL_NAN);
365: check53(1.0, DBL_POS_INF, GMP_RNDN, DBL_POS_INF);
366: check53(-1.0, DBL_POS_INF, GMP_RNDN, DBL_NEG_INF);
367: check53(DBL_NAN, 0.0, GMP_RNDN, DBL_NAN);
368: check53(1.0, DBL_NAN, GMP_RNDN, DBL_NAN);
369: #endif
370: check53(6.9314718055994530941514e-1, 0.0, GMP_RNDZ, 0.0);
371: check53(0.0, 6.9314718055994530941514e-1, GMP_RNDZ, 0.0);
372: check_sign();
373: check53(-4.165000000e4, -0.00004801920768307322868063274915, GMP_RNDN, 2.0);
374: check53(2.71331408349172961467e-08, -6.72658901114033715233e-165, GMP_RNDZ,
375: -1.8251348697787782844e-172);
376: check53(0.31869277231188065, 0.88642843322303122, GMP_RNDZ,
377: 2.8249833483992453642e-1);
378: check(8.47622108205396074254e-01, 3.24039313247872939883e-01, GMP_RNDU,
379: 28, 45, 2, 0.375);
380: check(2.63978122803639081440e-01, 6.8378615379333496093e-1, GMP_RNDN,
381: 34, 23, 31, 0.180504585267044603);
382: check(1.0, 0.11835170935876249132, GMP_RNDU, 6, 41, 36, 0.1183517093595583);
383: check53(67108865.0, 134217729.0, GMP_RNDN, 9.007199456067584e15);
384: check(1.37399642157394197284e-01, 2.28877275604219221350e-01, GMP_RNDN,
385: 49, 15, 32, 0.0314472340833162888);
386: check(4.03160720978664954828e-01, 5.85483042917246621073e-01, GMP_RNDZ,
387: 51, 22, 32, 0.2360436821472831);
388: check(3.90798504668055102229e-14, 9.85394674650308388664e-04, GMP_RNDN,
389: 46, 22, 12, 0.385027296503914762e-16);
390: check(4.58687081072827851358e-01, 2.20543551472118792844e-01, GMP_RNDN,
391: 49, 3, 2, 0.09375);
392: check_max();
393: check_min();
394: #ifdef MPFR_HAVE_FESETROUND
395: SEED_RAND (time(NULL));
396: prec = (argc<2) ? 53 : atoi(argv[1]);
397: rnd_mode = (argc<3) ? -1 : atoi(argv[2]);
398: for (i=0;i<1000000;) {
399: x = drand();
400: y = drand();
401: z = x*y; if (z<0) z=-z;
402: if (z<1e+308 && z>1e-308) /* don't test overflow/underflow for now */
403: { i++;
404: check(x, y, (rnd_mode==-1) ? LONG_RAND()%4 : rnd_mode,
405: prec, prec, prec, 0.0);
406: }
407: }
408: #endif
409:
410: return 0;
411: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>