MPFR v4.0.2
[mpfr.git] / tests / tnext.c
1 /* Test file for mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward.
2
3 Copyright 2003-2019 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 /* Generic tests for mpfr_nextabove and mpfr_nextbelow */
26 static void
27 generic_abovebelow (void)
28 {
29   int i;
30
31   for (i = 0; i < 20000; i++)
32     {
33       mpfr_t x, y, z, t;
34       mpfr_prec_t prec;
35       int neg, below;
36
37       prec = (randlimb () % 300) + MPFR_PREC_MIN;
38       mpfr_inits2 (prec, x, y, z, (mpfr_ptr) 0);
39       mpfr_init2 (t, 3);
40
41       /* special tests (executed once is enough) */
42       if (i == 0)
43         {
44           mpfr_set_nan (x);
45           mpfr_nextabove (x);
46           MPFR_ASSERTN(mpfr_nan_p (x));
47           mpfr_nextbelow (x);
48           MPFR_ASSERTN(mpfr_nan_p (x));
49           mpfr_nexttoward (x, y);
50           MPFR_ASSERTN(mpfr_nan_p (x));
51           mpfr_set_ui (y, 1, MPFR_RNDN);
52           mpfr_nexttoward (y, x);
53           MPFR_ASSERTN(mpfr_nan_p (y));
54           mpfr_set_ui (x, 1, MPFR_RNDN);
55           mpfr_set_ui (y, 1, MPFR_RNDN);
56           mpfr_nexttoward (x, y);
57           MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
58         }
59
60       do
61         mpfr_urandomb (x, RANDS);
62       while (mpfr_cmp_ui (x, 0) == 0);
63       neg = randlimb () & 1;
64       if (neg)
65         mpfr_neg (x, x, MPFR_RNDN);
66       mpfr_set (y, x, MPFR_RNDN);
67       below = randlimb () & 1;
68       if (below)
69         mpfr_nextbelow (y);
70       else
71         mpfr_nextabove (y);
72       mpfr_set_si (t, below ? -5 : 5, MPFR_RNDN);
73       mpfr_mul_2si (t, t, (mpfr_get_exp) (x) - prec - 3, MPFR_RNDN);
74       /* t = (1/2 + 1/8) ulp(x) */
75       mpfr_add (z, x, t, MPFR_RNDN);
76       if (!mpfr_number_p (y) || mpfr_cmp (y, z) != 0)
77         {
78           printf ("Error in mpfr_next%s for\n",
79                   below ? "below" : "above");
80           mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
81           printf (", got\n");
82           mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
83           printf (" instead of\n");
84           mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN);
85           printf ("\n");
86           exit (1);
87         }
88       mpfr_clears (x, y, z, t, (mpfr_ptr) 0);
89     }
90 }
91
92 static void
93 inverse_test (void)
94 {
95   static const char *tests[] = { "0", "1", "2", "3.1", "Inf" };
96   int i, neg, below;
97   mpfr_prec_t prec;
98
99   for (i = 0; i < numberof (tests); i++)
100     for (neg = 0; neg <= 1; neg++)
101       for (below = 0; below <= 1; below++)
102         for (prec = MPFR_PREC_MIN; prec < 200; prec += 3)
103           {
104             mpfr_t x, y;
105             int sign;
106
107             mpfr_inits2 (prec, x, y, (mpfr_ptr) 0);
108             mpfr_set_str (x, tests[i], 10, MPFR_RNDN);
109             if (neg)
110               mpfr_neg (x, x, MPFR_RNDN);
111             mpfr_set (y, x, MPFR_RNDN);
112             if (below)
113               mpfr_nextbelow (y);
114             else
115               mpfr_nextabove (y);
116             sign = MPFR_SIGN (y);
117             if (!(neg == below && mpfr_inf_p (x)))  /* then x = y */
118               {
119                 if (mpfr_cmp (x, y) == 0)
120                   {
121                     printf ("Error in inverse_test for %s, neg = %d,"
122                             " below = %d, prec = %d: x = y", tests[i],
123                             neg, below, (int) prec);
124                     printf ("\nx = ");
125                     mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
126                     printf ("\ny = ");
127                     mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
128                     printf ("\n");
129                     exit (1);
130                  }
131                 mpfr_nexttoward (y, x);
132                 if (mpfr_cmp_ui (y, 0) == 0 && MPFR_SIGN (y) != sign)
133                   {
134                     printf ("Sign error in inverse_test for %s, neg = %d,"
135                             " below = %d, prec = %d\n", tests[i], neg,
136                             below, (int) prec);
137                     mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
138                     printf ("\n");
139                     exit (1);
140                   }
141               }
142             if (mpfr_cmp (x, y) != 0)
143               {
144                 printf ("Error in inverse_test for %s, neg = %d, below = %d,"
145                         " prec = %d", tests[i], neg, below, (int) prec);
146                 printf ("\nx = ");
147                 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
148                 printf ("\ny = ");
149                 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
150                 printf ("\n");
151                 exit (1);
152               }
153             mpfr_clears (x, y, (mpfr_ptr) 0);
154           }
155 }
156
157 int
158 main (void)
159 {
160   tests_start_mpfr ();
161   generic_abovebelow ();
162   inverse_test ();
163   tests_end_mpfr ();
164   return 0;
165 }