1 /* Generic test file for functions with one mpfr_t argument and an integer.
2
3 Copyright 2005-2023 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 /* 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
test_generic_ui(mpfr_prec_t p0,mpfr_prec_t p1,unsigned int N)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 if (n < 2 || n > 3 || prec < p1)
68 u = INT_RAND_FUNCTION ();
69 else
70 {
71 /* Special cases tested in precision p1 if n = 2 or 3. */
72 if ((INTEGER_TYPE) -1 < 0) /* signed, type long assumed */
73 u = n == 2 ? LONG_MIN : LONG_MAX;
74 else /* unsigned */
75 u = n == 2 ? 0 : -1;
76 }
77 rnd = RND_RAND_NO_RNDF ();
78 mpfr_set_prec (y, yprec);
79 compare = TEST_FUNCTION (y, x, u, rnd);
80 if (mpfr_can_round (y, yprec, rnd, rnd, prec))
81 {
82 mpfr_set (t, y, rnd);
83 inexact = TEST_FUNCTION (z, x, u, rnd);
84 if (mpfr_cmp (t, z))
85 {
86 printf ("results differ for x=");
87 mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
88 printf ("\nu=%lu", (unsigned long) u);
89 printf (" prec=%lu rnd_mode=%s\n",
90 (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
91 #ifdef TEST_FUNCTION_NAME
92 printf ("Function: %s\n", TEST_FUNCTION_NAME);
93 #endif
94 printf ("got ");
95 mpfr_dump (z);
96 printf ("expected ");
97 mpfr_dump (t);
98 printf ("approx ");
99 mpfr_dump (y);
100 exit (1);
101 }
102 compare2 = mpfr_cmp (t, y);
103 /* if rounding to nearest, cannot know the sign of t - f(x)
104 because of composed rounding: y = o(f(x)) and t = o(y) */
105 if (compare * compare2 >= 0)
106 compare = compare + compare2;
107 else
108 compare = inexact; /* cannot determine sign(t-f(x)) */
109 if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF)
110 {
111 printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
112 "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
113 printf ("x = "); mpfr_dump (x);
114 printf ("u = %lu\n", (unsigned long) u);
115 printf ("y = "); mpfr_dump (y);
116 printf ("t = "); mpfr_dump (t);
117 exit (1);
118 }
119 }
120 }
121 }
122
123 mpfr_clear (x);
124 mpfr_clear (y);
125 mpfr_clear (z);
126 mpfr_clear (t);
127 }
128
129 #undef RAND_FUNCTION
130 #undef INTEGER_TYPE
131 #undef TEST_FUNCTION
132 #undef TEST_FUNCTION_NAME
133 #undef test_generic_ui
134 #undef INT_RAND_FUNCTION
135