xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/taway.c (revision 2718af68c3efc72c9769069b5c7f9ed36f6b9def)
1 /* Test file for round away.
2 
3 Copyright 2000-2020 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 https://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 "mpfr-test.h"
24 
25 #define DISP(s,t)                                       \
26   do                                                    \
27     {                                                   \
28       printf (s);                                       \
29       mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN);        \
30     }                                                   \
31   while (0)
32 
33 #define DISP2(s,t) do { DISP(s,t); putchar ('\n'); } while (0)
34 
35 #define SPECIAL_MAX 12
36 
37 static void
38 set_special (mpfr_ptr x, unsigned int select)
39 {
40   MPFR_ASSERTN (select < SPECIAL_MAX);
41   switch (select)
42     {
43     case 0:
44       MPFR_SET_NAN (x);
45       break;
46     case 1:
47       MPFR_SET_INF (x);
48       MPFR_SET_POS (x);
49       break;
50     case 2:
51       MPFR_SET_INF (x);
52       MPFR_SET_NEG (x);
53       break;
54     case 3:
55       MPFR_SET_ZERO (x);
56       MPFR_SET_POS  (x);
57       break;
58     case 4:
59       MPFR_SET_ZERO (x);
60       MPFR_SET_NEG  (x);
61       break;
62     case 5:
63       mpfr_set_str_binary (x, "1");
64       break;
65     case 6:
66       mpfr_set_str_binary (x, "-1");
67       break;
68     case 7:
69       mpfr_set_str_binary (x, "1e-1");
70       break;
71     case 8:
72       mpfr_set_str_binary (x, "1e+1");
73       break;
74     case 9:
75       mpfr_const_pi (x, MPFR_RNDN);
76       break;
77     case 10:
78       mpfr_const_pi (x, MPFR_RNDN);
79       MPFR_SET_EXP (x, MPFR_GET_EXP (x)-1);
80       break;
81     default:
82       mpfr_urandomb (x, RANDS);
83       break;
84     }
85 }
86 /* same than mpfr_cmp, but returns 0 for both NaN's */
87 static int
88 mpfr_compare (mpfr_srcptr a, mpfr_srcptr b)
89 {
90   return (MPFR_IS_NAN(a)) ? !MPFR_IS_NAN(b) :
91     (MPFR_IS_NAN(b) || mpfr_cmp(a, b));
92 }
93 
94 static void
95 test3 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_rnd_t),
96        const char *foo)
97 {
98   mpfr_t ref1, ref2, ref3;
99   mpfr_t res1;
100   mpfr_prec_t p1, p2, p3;
101   int i, inexa, inexd;
102   mpfr_rnd_t r;
103 
104   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
105   p2 = (randlimb () % 200) + MPFR_PREC_MIN;
106   p3 = (randlimb () % 200) + MPFR_PREC_MIN;
107 
108   mpfr_init2 (ref1, p1);
109   mpfr_init2 (ref2, p2);
110   mpfr_init2 (ref3, p3);
111   mpfr_init2 (res1, p1);
112 
113   /* for each variable, consider each of the following 6 possibilities:
114      NaN, +Infinity, -Infinity, +0, -0 or a random number */
115   for (i = 0; i < SPECIAL_MAX * SPECIAL_MAX; i++)
116     {
117       set_special (ref2, i%SPECIAL_MAX);
118       set_special (ref3, i/SPECIAL_MAX);
119 
120       inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
121       r = MPFR_IS_POS (res1) ? MPFR_RNDU : MPFR_RNDD;
122       inexd = testfunc (ref1, ref2, ref3, r);
123 
124       if (mpfr_compare (res1, ref1) || inexa != inexd)
125         {
126           printf ("Error with RNDA for %s with ", foo);
127           DISP("x=",ref2); DISP2(", y=",ref3);
128           printf ("inexa=%d inexd=%d\n", inexa, inexd);
129           printf ("expected "); mpfr_dump (ref1);
130           printf ("got      "); mpfr_dump (res1);
131           exit (1);
132         }
133     }
134 
135   mpfr_clear (ref1);
136   mpfr_clear (ref2);
137   mpfr_clear (ref3);
138   mpfr_clear (res1);
139 }
140 
141 static void
142 test4 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_srcptr, mpfr_srcptr,
143                        mpfr_rnd_t), const char *foo)
144 {
145   mpfr_t ref, op1, op2, op3;
146   mpfr_prec_t pout, p1, p2, p3;
147   mpfr_t res;
148   int i, j, k, inexa, inexd;
149   mpfr_rnd_t r;
150 
151   pout = (randlimb () % 200) + MPFR_PREC_MIN;
152   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
153   p2 = (randlimb () % 200) + MPFR_PREC_MIN;
154   p3 = (randlimb () % 200) + MPFR_PREC_MIN;
155 
156   mpfr_init2 (ref, pout);
157   mpfr_init2 (res, pout);
158   mpfr_init2 (op1, p1);
159   mpfr_init2 (op2, p2);
160   mpfr_init2 (op3, p3);
161 
162   /* for each variable, consider each of the following 6 possibilities:
163      NaN, +Infinity, -Infinity, +0, -0 or a random number */
164 
165   for (i = 0; i < SPECIAL_MAX; i++)
166     {
167       set_special (op1, i);
168       for (j = 0; j < SPECIAL_MAX; j++)
169         {
170           set_special (op2, j);
171           for (k = 0; k < SPECIAL_MAX; k++)
172             {
173               set_special (op3, k);
174 
175               inexa = testfunc (res, op1, op2, op3, MPFR_RNDA);
176               r = MPFR_IS_POS (res) ? MPFR_RNDU : MPFR_RNDD;
177               inexd = testfunc (ref, op1, op2, op3, r);
178 
179               if (mpfr_compare (res, ref) || inexa != inexd)
180                 {
181                   printf ("Error with RNDA for %s with ", foo);
182                   DISP("a=", op1); DISP(", b=", op2); DISP2(", c=", op3);
183                   printf ("inexa=%d inexd=%d\n", inexa, inexd);
184                   DISP("expected ", ref); DISP2(", got ", res);
185                   exit (1);
186                 }
187             }
188         }
189     }
190 
191   mpfr_clear (ref);
192   mpfr_clear (op1);
193   mpfr_clear (op2);
194   mpfr_clear (op3);
195   mpfr_clear (res);
196 }
197 
198 static void
199 test2ui (int (*testfunc)(mpfr_ptr, mpfr_srcptr, unsigned long int, mpfr_rnd_t),
200          const char *foo)
201 {
202   mpfr_t ref1, ref2;
203   unsigned int ref3;
204   mpfr_t res1;
205   mpfr_prec_t p1, p2;
206   int i, inexa, inexd;
207   mpfr_rnd_t r;
208 
209   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
210   p2 = (randlimb () % 200) + MPFR_PREC_MIN;
211 
212   mpfr_init2 (ref1, p1);
213   mpfr_init2 (ref2, p2);
214   mpfr_init2 (res1, p1);
215 
216   /* ref2 can be NaN, +Inf, -Inf, +0, -0 or any number
217      ref3 can be 0 or any number */
218   for (i = 0; i < SPECIAL_MAX * 2; i++)
219     {
220       set_special (ref2, i % SPECIAL_MAX);
221       ref3 = i / SPECIAL_MAX == 0 ? 0 : randlimb ();
222 
223       inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
224       r = MPFR_IS_POS (res1) ? MPFR_RNDU : MPFR_RNDD;
225       inexd = testfunc (ref1, ref2, ref3, r);
226 
227       if (mpfr_compare (res1, ref1) || inexa != inexd)
228         {
229           printf ("Error with RNDA for %s for c=%u\n", foo, ref3);
230           DISP2("a=",ref2);
231           printf ("inexa=%d inexd=%d\n", inexa, inexd);
232           printf ("expected "); mpfr_dump (ref1);
233           printf ("got      "); mpfr_dump (res1);
234           exit (1);
235         }
236     }
237 
238   mpfr_clear (ref1);
239   mpfr_clear (ref2);
240   mpfr_clear (res1);
241 }
242 
243 static void
244 testui2 (int (*testfunc)(mpfr_ptr, unsigned long int, mpfr_srcptr, mpfr_rnd_t),
245          const char *foo)
246 {
247   mpfr_t ref1, ref3;
248   unsigned int ref2;
249   mpfr_t res1;
250   mpfr_prec_t p1, p3;
251   int i, inexa, inexd;
252   mpfr_rnd_t r;
253 
254   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
255   p3 = (randlimb () % 200) + MPFR_PREC_MIN;
256 
257   mpfr_init2 (ref1, p1);
258   mpfr_init2 (ref3, p3);
259   mpfr_init2 (res1, p1);
260 
261   for (i = 0; i < SPECIAL_MAX * 2; i++)
262     {
263       set_special (ref3, i % SPECIAL_MAX);
264       ref2 = i / SPECIAL_MAX == 0 ? 0 : randlimb ();
265 
266       inexa = testfunc (res1, ref2, ref3, MPFR_RNDA);
267       r = MPFR_IS_POS (res1) ? MPFR_RNDU : MPFR_RNDD;
268       inexd = testfunc (ref1, ref2, ref3, r);
269 
270       if (mpfr_compare (res1, ref1) || inexa != inexd)
271         {
272           printf ("Error with RNDA for %s for b=%u\n", foo, ref2);
273           DISP2("a=", ref3);
274           printf ("inexa=%d inexd=%d\n", inexa, inexd);
275           DISP("expected ", ref1); DISP2(", got ", res1);
276           exit (1);
277         }
278     }
279 
280   mpfr_clear (ref1);
281   mpfr_clear (ref3);
282   mpfr_clear (res1);
283 }
284 
285 /* foo(mpfr_ptr, mpfr_srcptr, mp_rndt) */
286 static void
287 test2 (int (*testfunc)(mpfr_ptr, mpfr_srcptr, mpfr_rnd_t), const char *foo)
288 {
289   mpfr_t ref1, ref2;
290   mpfr_t res1;
291   mpfr_prec_t p1, p2;
292   int i, inexa, inexd;
293   mpfr_rnd_t r;
294 
295   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
296   p2 = (randlimb () % 200) + MPFR_PREC_MIN;
297 
298   mpfr_init2 (ref1, p1);
299   mpfr_init2 (ref2, p2);
300   mpfr_init2 (res1, p1);
301 
302   for (i = 0; i < SPECIAL_MAX; i++)
303     {
304       set_special (ref2, i);
305 
306       /* first round to away */
307       inexa = testfunc (res1, ref2, MPFR_RNDA);
308 
309       r = MPFR_IS_POS (res1) ? MPFR_RNDU : MPFR_RNDD;
310       inexd = testfunc (ref1, ref2, r);
311       if (mpfr_compare (res1, ref1) || inexa != inexd)
312         {
313           printf ("Error with RNDA for %s with ", foo);
314           DISP2("x=", ref2);
315           printf ("inexa=%d inexd=%d\n", inexa, inexd);
316           DISP("expected ", ref1); DISP2(", got ", res1);
317           exit (1);
318         }
319     }
320 
321   mpfr_clear (ref1);
322   mpfr_clear (ref2);
323   mpfr_clear (res1);
324 }
325 
326 /* one operand, two results, like mpfr_sin_cos */
327 static void
328 test3a (int (*testfunc)(mpfr_ptr, mpfr_ptr, mpfr_srcptr, mpfr_rnd_t),
329         const char *foo)
330 {
331   mpfr_t ref1, ref2, ref3;
332   mpfr_t res1, res2;
333   mpfr_prec_t p1, p2, p3;
334   int i, inexa, inexd;
335   mpfr_rnd_t r;
336 
337   p1 = (randlimb () % 200) + MPFR_PREC_MIN;
338   p2 = (randlimb () % 200) + MPFR_PREC_MIN;
339   p3 = (randlimb () % 200) + MPFR_PREC_MIN;
340 
341   mpfr_init2 (ref1, p1);
342   mpfr_init2 (ref2, p2);
343   mpfr_init2 (ref3, p3);
344   mpfr_init2 (res1, p1);
345   mpfr_init2 (res2, p2);
346 
347   for (i = 0; i < SPECIAL_MAX; i++)
348     {
349       set_special (ref3, i);
350 
351       inexa = testfunc (res1, res2, ref3, MPFR_RNDA);
352 
353       /* first check wrt the first operand */
354       r = MPFR_IS_POS (res1) ? MPFR_RNDU : MPFR_RNDD;
355       inexd = testfunc (ref1, ref2, ref3, r);
356       /* the low 2 bits of the inexact flag concern the 1st operand */
357       if (mpfr_compare (res1, ref1) || (inexa & 3) != (inexd & 3))
358         {
359           printf ("Error with RNDA for %s (1st operand)\n", foo);
360           DISP2("a=",ref3);
361           DISP("expected ", ref1); printf ("\n");
362           DISP("got      ", res1); printf ("\n");
363           printf ("inexa=%d inexd=%d\n", inexa & 3, inexd & 3);
364           exit (1);
365         }
366 
367       /* now check wrt the second operand */
368       r = MPFR_IS_POS (res2) ? MPFR_RNDU : MPFR_RNDD;
369       inexd = testfunc (ref1, ref2, ref3, r);
370       /* bits 2..3 of the inexact flag concern the 2nd operand */
371       if (mpfr_compare (res2, ref2) || (inexa >> 2) != (inexd >> 2))
372         {
373           printf ("Error with RNDA for %s (2nd operand)\n", foo);
374           DISP2("a=",ref3);
375           DISP("expected ", ref2); printf ("\n");
376           DISP("got      ", res2); printf ("\n");
377           printf ("inexa=%d inexd=%d\n", inexa >> 2, inexd >> 2);
378           exit (1);
379         }
380 
381     }
382 
383   mpfr_clear (ref1);
384   mpfr_clear (ref2);
385   mpfr_clear (ref3);
386   mpfr_clear (res1);
387   mpfr_clear (res2);
388 }
389 
390 int
391 main (void)
392 {
393   int N = 20;
394 
395   tests_start_mpfr ();
396 
397   while (N--)
398     {
399       /* no need to test mpfr_round, mpfr_ceil, mpfr_floor, mpfr_trunc since
400          they take no rounding mode */
401 
402       test2ui (mpfr_add_ui, "mpfr_add_ui");
403       test2ui (mpfr_div_2exp, "mpfr_div_2exp");
404       test2ui (mpfr_div_2ui, "mpfr_div_2ui");
405       test2ui (mpfr_div_ui, "mpfr_div_ui");
406       test2ui (mpfr_mul_2exp, "mpfr_mul_2exp");
407       test2ui (mpfr_mul_2ui, "mpfr_mul_2ui");
408       test2ui (mpfr_mul_ui, "mpfr_mul_ui");
409       test2ui (mpfr_pow_ui, "mpfr_pow_ui");
410       test2ui (mpfr_sub_ui, "mpfr_sub_ui");
411 
412       testui2 (mpfr_ui_div, "mpfr_ui_div");
413       testui2 (mpfr_ui_sub, "mpfr_ui_sub");
414       testui2 (mpfr_ui_pow, "mpfr_ui_pow");
415 
416       test2 (mpfr_sqr, "mpfr_sqr");
417       test2 (mpfr_sqrt, "mpfr_sqrt");
418       test2 (mpfr_abs, "mpfr_abs");
419       test2 (mpfr_neg, "mpfr_neg");
420 
421       test2 (mpfr_log, "mpfr_log");
422       test2 (mpfr_log2, "mpfr_log2");
423       test2 (mpfr_log10, "mpfr_log10");
424       test2 (mpfr_log1p, "mpfr_log1p");
425 
426       test2 (mpfr_exp, "mpfr_exp");
427       test2 (mpfr_exp2, "mpfr_exp2");
428       test2 (mpfr_exp10, "mpfr_exp10");
429       test2 (mpfr_expm1, "mpfr_expm1");
430       test2 (mpfr_eint, "mpfr_eint");
431 
432       test2 (mpfr_sinh, "mpfr_sinh");
433       test2 (mpfr_cosh, "mpfr_cosh");
434       test2 (mpfr_tanh, "mpfr_tanh");
435       test2 (mpfr_asinh, "mpfr_asinh");
436       test2 (mpfr_acosh, "mpfr_acosh");
437       test2 (mpfr_atanh, "mpfr_atanh");
438       test2 (mpfr_sech, "mpfr_sech");
439       test2 (mpfr_csch, "mpfr_csch");
440       test2 (mpfr_coth, "mpfr_coth");
441 
442       test2 (mpfr_asin, "mpfr_asin");
443       test2 (mpfr_acos, "mpfr_acos");
444       test2 (mpfr_atan, "mpfr_atan");
445       test2 (mpfr_cos, "mpfr_cos");
446       test2 (mpfr_sin, "mpfr_sin");
447       test2 (mpfr_tan, "mpfr_tan");
448       test2 (mpfr_sec, "mpfr_sec");
449       test2 (mpfr_csc, "mpfr_csc");
450       test2 (mpfr_cot, "mpfr_cot");
451 
452       test2 (mpfr_erf,  "mpfr_erf");
453       test2 (mpfr_erfc, "mpfr_erfc");
454       test2 (mpfr_j0,   "mpfr_j0");
455       test2 (mpfr_j1,   "mpfr_j1");
456       test2 (mpfr_y0,   "mpfr_y0");
457       test2 (mpfr_y1,   "mpfr_y1");
458       test2 (mpfr_zeta, "mpfr_zeta");
459       test2 (mpfr_gamma, "mpfr_gamma");
460       test2 (mpfr_lngamma, "mpfr_lngamma");
461 
462       test2 (mpfr_rint, "mpfr_rint");
463       test2 (mpfr_rint_ceil, "mpfr_rint_ceil");
464       test2 (mpfr_rint_floor, "mpfr_rint_floor");
465       test2 (mpfr_rint_round, "mpfr_rint_round");
466       test2 (mpfr_rint_trunc, "mpfr_rint_trunc");
467       test2 (mpfr_frac, "mpfr_frac");
468 
469       test3 (mpfr_add, "mpfr_add");
470       test3 (mpfr_sub, "mpfr_sub");
471       test3 (mpfr_mul, "mpfr_mul");
472       test3 (mpfr_div, "mpfr_div");
473 
474       test3 (mpfr_agm, "mpfr_agm");
475       test3 (mpfr_min, "mpfr_min");
476       test3 (mpfr_max, "mpfr_max");
477 
478       /* we don't test reldiff since it does not guarantee correct rounding,
479          thus we can get different results with RNDA and RNDU or RNDD. */
480       test3 (mpfr_dim, "mpfr_dim");
481 
482       test3 (mpfr_remainder, "mpfr_remainder");
483       test3 (mpfr_pow, "mpfr_pow");
484       test3 (mpfr_atan2, "mpfr_atan2");
485       test3 (mpfr_hypot, "mpfr_hypot");
486 
487       test3a (mpfr_sin_cos, "mpfr_sin_cos");
488 
489       test4 (mpfr_fma, "mpfr_fma");
490       test4 (mpfr_fms, "mpfr_fms");
491 
492       test2 (mpfr_li2, "mpfr_li2");
493       test2 (mpfr_rec_sqrt, "mpfr_rec_sqrt");
494       test3 (mpfr_fmod, "mpfr_fmod");
495       test3a (mpfr_modf, "mpfr_modf");
496       test3a (mpfr_sinh_cosh, "mpfr_sinh_cosh");
497 
498 #if MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)
499       test2 (mpfr_ai, "mpfr_ai");
500       test2 (mpfr_digamma, "mpfr_digamma");
501 #endif
502     }
503 
504   tests_end_mpfr ();
505   return 0;
506 }
507