xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tgeneric_ui.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1efee5258Smrg /* Generic test file for functions with one mpfr_t argument and an integer.
2efee5258Smrg 
3*ba125506Smrg Copyright 2005-2023 Free Software Foundation, Inc.
4efdec83bSmrg Contributed by the AriC and Caramba projects, INRIA.
5efee5258Smrg 
6efee5258Smrg This file is part of the GNU MPFR Library.
7efee5258Smrg 
8efee5258Smrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9efee5258Smrg it under the terms of the GNU Lesser General Public License as published by
10efee5258Smrg the Free Software Foundation; either version 3 of the License, or (at your
11efee5258Smrg option) any later version.
12efee5258Smrg 
13efee5258Smrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14efee5258Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15efee5258Smrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16efee5258Smrg License for more details.
17efee5258Smrg 
18efee5258Smrg You should have received a copy of the GNU Lesser General Public License
19efee5258Smrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
202ba2404bSmrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21efee5258Smrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22efee5258Smrg 
23efee5258Smrg /* define INTEGER_TYPE to what we want */
24efee5258Smrg #ifndef INTEGER_TYPE
25efee5258Smrg # define INTEGER_TYPE mp_limb_t
26efee5258Smrg #endif
27efee5258Smrg #ifndef RAND_FUNCTION
28efee5258Smrg # define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS)
29efee5258Smrg #endif
30efee5258Smrg #ifndef INT_RAND_FUNCTION
31efee5258Smrg # define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb ()
32efee5258Smrg #endif
33efee5258Smrg 
34efee5258Smrg static void
test_generic_ui(mpfr_prec_t p0,mpfr_prec_t p1,unsigned int N)35efee5258Smrg test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N)
36efee5258Smrg {
37efee5258Smrg   mpfr_prec_t prec, yprec;
38efee5258Smrg   mpfr_t x, y, z, t;
39efee5258Smrg   INTEGER_TYPE u;
40efee5258Smrg   mpfr_rnd_t rnd;
41efee5258Smrg   int inexact, compare, compare2;
42efee5258Smrg   unsigned int n;
43efee5258Smrg 
44efee5258Smrg   mpfr_init (x);
45efee5258Smrg   mpfr_init (y);
46efee5258Smrg   mpfr_init (z);
47efee5258Smrg   mpfr_init (t);
48efee5258Smrg 
49efee5258Smrg   /* generic test */
50efee5258Smrg   for (prec = p0; prec <= p1; prec++)
51efee5258Smrg     {
52efee5258Smrg       mpfr_set_prec (x, prec);
53efee5258Smrg       mpfr_set_prec (z, prec);
54efee5258Smrg       mpfr_set_prec (t, prec);
55efee5258Smrg       yprec = prec + 10;
56efee5258Smrg 
57efee5258Smrg       for (n = 0; n <= N; n++)
58efee5258Smrg         {
59efee5258Smrg           if (n > 1 || prec < p1)
60efee5258Smrg             RAND_FUNCTION (x);
61efee5258Smrg           else
62efee5258Smrg             {
63efee5258Smrg               /* Special cases tested in precision p1 if n <= 1. */
64efee5258Smrg               mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN);
65efee5258Smrg               mpfr_set_exp (x, mpfr_get_emin ());
66efee5258Smrg             }
67efdec83bSmrg           if (n < 2 || n > 3 || prec < p1)
68efee5258Smrg             u = INT_RAND_FUNCTION ();
69efdec83bSmrg           else
70efdec83bSmrg             {
71efdec83bSmrg               /* Special cases tested in precision p1 if n = 2 or 3. */
72efdec83bSmrg               if ((INTEGER_TYPE) -1 < 0)  /* signed, type long assumed */
73efdec83bSmrg                 u = n == 2 ? LONG_MIN : LONG_MAX;
74efdec83bSmrg               else  /* unsigned */
75efdec83bSmrg                 u = n == 2 ? 0 : -1;
76efdec83bSmrg             }
77299c6f0cSmrg           rnd = RND_RAND_NO_RNDF ();
78efee5258Smrg           mpfr_set_prec (y, yprec);
79efee5258Smrg           compare = TEST_FUNCTION (y, x, u, rnd);
80efee5258Smrg           if (mpfr_can_round (y, yprec, rnd, rnd, prec))
81efee5258Smrg             {
82efee5258Smrg               mpfr_set (t, y, rnd);
83efee5258Smrg               inexact = TEST_FUNCTION (z, x, u, rnd);
84efee5258Smrg               if (mpfr_cmp (t, z))
85efee5258Smrg                 {
86efee5258Smrg                   printf ("results differ for x=");
87efee5258Smrg                   mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN);
88efee5258Smrg                   printf ("\nu=%lu", (unsigned long) u);
89efee5258Smrg                   printf (" prec=%lu rnd_mode=%s\n",
90efee5258Smrg                           (unsigned long ) prec, mpfr_print_rnd_mode (rnd));
91efee5258Smrg #ifdef TEST_FUNCTION_NAME
92efee5258Smrg                   printf ("Function: %s\n", TEST_FUNCTION_NAME);
93efee5258Smrg #endif
94efee5258Smrg                   printf ("got      ");
95299c6f0cSmrg                   mpfr_dump (z);
96efee5258Smrg                   printf ("expected ");
97299c6f0cSmrg                   mpfr_dump (t);
98efee5258Smrg                   printf ("approx   ");
99299c6f0cSmrg                   mpfr_dump (y);
100efee5258Smrg                   exit (1);
101efee5258Smrg                 }
102efee5258Smrg               compare2 = mpfr_cmp (t, y);
103efee5258Smrg               /* if rounding to nearest, cannot know the sign of t - f(x)
104efee5258Smrg                  because of composed rounding: y = o(f(x)) and t = o(y) */
105efee5258Smrg               if (compare * compare2 >= 0)
106efee5258Smrg                 compare = compare + compare2;
107efee5258Smrg               else
108efee5258Smrg                 compare = inexact; /* cannot determine sign(t-f(x)) */
109299c6f0cSmrg               if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF)
110efee5258Smrg                 {
111efee5258Smrg                   printf ("Wrong inexact flag for rnd=%s: expected %d, got %d"
112efee5258Smrg                           "\n", mpfr_print_rnd_mode (rnd), compare, inexact);
113efdec83bSmrg                   printf ("x = "); mpfr_dump (x);
114efdec83bSmrg                   printf ("u = %lu\n", (unsigned long) u);
115efdec83bSmrg                   printf ("y = "); mpfr_dump (y);
116efdec83bSmrg                   printf ("t = "); mpfr_dump (t);
117efee5258Smrg                   exit (1);
118efee5258Smrg                 }
119efee5258Smrg             }
120efee5258Smrg         }
121efee5258Smrg     }
122efee5258Smrg 
123efee5258Smrg   mpfr_clear (x);
124efee5258Smrg   mpfr_clear (y);
125efee5258Smrg   mpfr_clear (z);
126efee5258Smrg   mpfr_clear (t);
127efee5258Smrg }
128efee5258Smrg 
129efee5258Smrg #undef RAND_FUNCTION
130efee5258Smrg #undef INTEGER_TYPE
131efee5258Smrg #undef TEST_FUNCTION
132efee5258Smrg #undef TEST_FUNCTION_NAME
133efee5258Smrg #undef test_generic_ui
134efee5258Smrg #undef INT_RAND_FUNCTION
135