xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tgeneric_ui.c (revision dd255ccea4286b0c44fa8fd48a9a19a768afe8e1)
1 /* Generic test file for functions with one mpfr_t argument and an integer.
2 
3 Copyright 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 /* define INTEGER_TYPE to what we want */
24 #ifndef INTEGER_TYPE
25 # define INTEGER_TYPE mp_limb_t
26 #endif
27 #ifndef RAND_FUNCTION
28 # define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS)
29 #endif
30 #ifndef INT_RAND_FUNCTION
31 # define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb ()
32 #endif
33 
34 static void
35 test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
36 {
37   mpfr_prec_t prec, yprec;
38   mpfr_t x, y, z, t;
39   INTEGER_TYPE u;
40   mpfr_rnd_t rnd;
41   int inexact, compare, compare2;
42   unsigned int n;
43 
44   mpfr_init (x);
45   mpfr_init (y);
46   mpfr_init (z);
47   mpfr_init (t);
48 
49   /* generic test */
50   for (prec = p0; prec <= p1; prec++)
51     {
52       mpfr_set_prec (x, prec);
53       mpfr_set_prec (z, prec);
54       mpfr_set_prec (t, prec);
55       yprec = prec + 10;
56 
57       for (n = 0; n <= N; n++)
58         {
59           if (n > 1 || prec < p1)
60             RAND_FUNCTION (x);
61           else
62             {
63               /* Special cases tested in precision p1 if n <= 1. */
64               mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
65               mpfr_set_exp (x, mpfr_get_emin ());
66             }
67           u = INT_RAND_FUNCTION ();
68           rnd = RND_RAND ();
69           mpfr_set_prec (y, yprec);
70           compare = TEST_FUNCTION (y, x, u, rnd);
71           if (mpfr_can_round (y, yprec, rnd, rnd, prec))
72             {
73               mpfr_set (t, y, rnd);
74               inexact = TEST_FUNCTION (z, x, u, rnd);
75               if (mpfr_cmp (t, z))
76                 {
77                   printf ("results differ for x=");
78                   mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
79                   printf ("\nu=%lu", (unsigned long) u);
80                   printf (" prec=%lu rnd_mode=%s\n",
81                           (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
82 #ifdef TEST_FUNCTION_NAME
83                   printf ("Function: %s\n", TEST_FUNCTION_NAME);
84 #endif
85                   printf ("got      ");
86                   mpfr_out_str (stdout, 2, prec, z, MPFR_RNDN);
87                   puts ("");
88                   printf ("expected ");
89                   mpfr_out_str (stdout, 2, prec, t, MPFR_RNDN);
90                   puts ("");
91                   printf ("approx  ");
92                   mpfr_print_binary (y);
93                   puts ("");
94                   exit (1);
95                 }
96               compare2 = mpfr_cmp (t, y);
97               /* if rounding to nearest, cannot know the sign of t - f(x)
98                  because of composed rounding: y = o(f(x)) and t = o(y) */
99               if (compare * compare2 >= 0)
100                 compare = compare + compare2;
101               else
102                 compare = inexact; /* cannot determine sign(t-f(x)) */
103               if (((inexact == 0) && (compare != 0)) ||
104                   ((inexact > 0) && (compare <= 0)) ||
105                   ((inexact < 0) && (compare >= 0)))
106                 {
107                   printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
108                           "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
109                   printf ("x="); mpfr_print_binary (x); puts ("");
110                   printf ("u=%lu", (unsigned long) u);
111                   printf ("y="); mpfr_print_binary (y); puts ("");
112                   printf ("t="); mpfr_print_binary (t); puts ("");
113                   exit (1);
114                 }
115             }
116         }
117     }
118 
119   mpfr_clear (x);
120   mpfr_clear (y);
121   mpfr_clear (z);
122   mpfr_clear (t);
123 }
124 
125 #undef RAND_FUNCTION
126 #undef INTEGER_TYPE
127 #undef TEST_FUNCTION
128 #undef TEST_FUNCTION_NAME
129 #undef test_generic_ui
130 #undef INT_RAND_FUNCTION
131