xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset.c (revision 154bfe8e089c1a0a4e9ed8414f08d3da90949162)
1 /* Test file for mpfr_set.
2 
3 Copyright 2001-2018 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 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 #include "mpfr-test.h"
24 
25 static int error;
26 
27 #define PRINT_ERROR_IF(condition, text)         \
28   do {                                          \
29     if (condition)                              \
30       {                                         \
31         printf ("%s", text);                    \
32         error = 1;                              \
33       }                                         \
34   } while (0)
35 
36 
37 /* Maybe better create its own test file? */
38 static void
39 check_neg_special (void)
40 {
41   mpfr_t x, y;
42   int inexact;
43   int s1, s2, s3;
44 
45   mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
46 
47   MPFR_SET_NAN (x);
48   s1 = mpfr_signbit (x) != 0;
49 
50   mpfr_clear_nanflag ();
51   inexact = mpfr_neg (y, x, MPFR_RNDN);
52   s2 = mpfr_signbit (y) != 0;
53   PRINT_ERROR_IF (!mpfr_nanflag_p (),
54                   "ERROR: neg (NaN) doesn't set Nan flag (1).\n");
55   PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
56                   "ERROR: neg (NaN) failed to set variable to NaN (1).\n");
57   PRINT_ERROR_IF (s1 == s2,
58                   "ERROR: neg (NaN) doesn't correctly flip sign bit (1).\n");
59 
60   mpfr_clear_nanflag ();
61   inexact = mpfr_neg (x, x, MPFR_RNDN);
62   s2 = mpfr_signbit (x) != 0;
63   PRINT_ERROR_IF (!mpfr_nanflag_p (),
64                   "ERROR: neg (NaN) doesn't set Nan flag (2).\n");
65   PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0,
66                   "ERROR: neg (NaN) failed to set variable to NaN (2).\n");
67   /* check following "bug" is fixed:
68      https://sympa.inria.fr/sympa/arc/mpfr/2017-11/msg00003.html */
69   PRINT_ERROR_IF (s1 == s2,
70                   "ERROR: neg (NaN) doesn't correctly flip sign bit (2).\n");
71 
72   mpfr_clear_nanflag ();
73   inexact = mpfr_neg (y, x, MPFR_RNDN);
74   s3 = mpfr_signbit (y) != 0;
75   PRINT_ERROR_IF (!mpfr_nanflag_p (),
76                   "ERROR: neg (NaN) doesn't set Nan flag (3).\n");
77   PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
78                   "ERROR: neg (NaN) failed to set variable to NaN (3).\n");
79   PRINT_ERROR_IF (s2 == s3,
80                   "ERROR: neg (NaN) doesn't correctly flip sign bit (3).\n");
81 
82   mpfr_clear_nanflag ();
83   inexact = mpfr_neg (x, x, MPFR_RNDN);
84   s3 = mpfr_signbit (x) != 0;
85   PRINT_ERROR_IF (!mpfr_nanflag_p (),
86                   "ERROR: neg (NaN) doesn't set Nan flag (4).\n");
87   PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0,
88                   "ERROR: neg (NaN) failed to set variable to NaN (4).\n");
89   PRINT_ERROR_IF (s2 == s3,
90                   "ERROR: neg (NaN) doesn't correctly flip sign bit (4).\n");
91 
92   mpfr_clears (x, y, (mpfr_ptr) 0);
93 }
94 
95 static void
96 check_special (void)
97 {
98   mpfr_t x, y;
99   int inexact;
100   int s1, s2;
101 
102   mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
103 
104   mpfr_set_inf (x, 1);
105   PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0,
106                   "ERROR: mpfr_set_inf failed to set variable to +inf [1].\n");
107   mpfr_set_inf (x, INT_MAX);
108   PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0,
109                   "ERROR: mpfr_set_inf failed to set variable to +inf [2].\n");
110   mpfr_set_inf (x, 0);
111   PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) < 0,
112                   "ERROR: mpfr_set_inf failed to set variable to +inf [3].\n");
113   inexact = mpfr_set (y, x, MPFR_RNDN);
114   PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) < 0 || inexact != 0,
115                   "ERROR: mpfr_set failed to set variable to +infinity.\n");
116 
117   inexact = mpfr_set_ui (y, 0, MPFR_RNDN);
118   PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_NEG (y) || inexact != 0,
119                   "ERROR: mpfr_set_ui failed to set variable to +0.\n");
120 
121   mpfr_set_inf (x, -1);
122   PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0,
123                   "ERROR: mpfr_set_inf failed to set variable to -inf [1].\n");
124   mpfr_set_inf (x, INT_MIN);
125   PRINT_ERROR_IF (!mpfr_inf_p (x) || mpfr_sgn (x) > 0,
126                   "ERROR: mpfr_set_inf failed to set variable to -inf [2].\n");
127   inexact = mpfr_set (y, x, MPFR_RNDN);
128   PRINT_ERROR_IF (!mpfr_inf_p (y) || mpfr_sgn (y) > 0 || inexact != 0,
129                   "ERROR: mpfr_set failed to set variable to -infinity.\n");
130 
131   mpfr_set_zero (x, 1);
132   PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x),
133                   "ERROR: mpfr_set_zero failed to set variable to +0 [1].\n");
134   mpfr_set_zero (x, INT_MAX);
135   PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x),
136                   "ERROR: mpfr_set_zero failed to set variable to +0 [2].\n");
137   mpfr_set_zero (x, 0);
138   PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_NEG (x),
139                   "ERROR: mpfr_set_zero failed to set variable to +0 [3].\n");
140   inexact = mpfr_set (y, x, MPFR_RNDN);
141   PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_NEG (y) || inexact != 0,
142                   "ERROR: mpfr_set failed to set variable to +0.\n");
143 
144   mpfr_set_zero (x, -1);
145   PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_POS (x),
146                   "ERROR: mpfr_set_zero failed to set variable to -0 [1].\n");
147   mpfr_set_zero (x, INT_MIN);
148   PRINT_ERROR_IF (MPFR_NOTZERO (x) || MPFR_IS_POS (x),
149                   "ERROR: mpfr_set_zero failed to set variable to -0 [2].\n");
150   inexact = mpfr_set (y, x, MPFR_RNDN);
151   PRINT_ERROR_IF (MPFR_NOTZERO (y) || MPFR_IS_POS (y) || inexact != 0,
152                   "ERROR: mpfr_set failed to set variable to -0.\n");
153 
154   /* NaN tests */
155 
156   mpfr_set_nan (x);
157   PRINT_ERROR_IF (!mpfr_nan_p (x),
158                   "ERROR: mpfr_set_nan failed to set variable to NaN.\n");
159   s1 = mpfr_signbit (x) != 0;
160 
161   mpfr_clear_nanflag ();
162   inexact = mpfr_set (y, x, MPFR_RNDN);
163   s2 = mpfr_signbit (y) != 0;
164   PRINT_ERROR_IF (!mpfr_nanflag_p (),
165                   "ERROR: mpfr_set doesn't set Nan flag (1).\n");
166   PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
167                   "ERROR: mpfr_set failed to set variable to NaN (1).\n");
168   PRINT_ERROR_IF (s1 != s2,
169                   "ERROR: mpfr_set doesn't preserve the sign bit (1).\n");
170 
171   mpfr_clear_nanflag ();
172   inexact = mpfr_set (x, x, MPFR_RNDN);
173   s2 = mpfr_signbit (x) != 0;
174   PRINT_ERROR_IF (!mpfr_nanflag_p (),
175                   "ERROR: mpfr_set doesn't set Nan flag (2).\n");
176   PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0,
177                   "ERROR: mpfr_set failed to set variable to NaN (2).\n");
178   PRINT_ERROR_IF (s1 != s2,
179                   "ERROR: mpfr_set doesn't preserve the sign bit (2).\n");
180 
181   MPFR_CHANGE_SIGN (x);
182   s1 = !s1;
183 
184   mpfr_clear_nanflag ();
185   inexact = mpfr_set (y, x, MPFR_RNDN);
186   s2 = mpfr_signbit (y) != 0;
187   PRINT_ERROR_IF (!mpfr_nanflag_p (),
188                   "ERROR: mpfr_set doesn't set Nan flag (3).\n");
189   PRINT_ERROR_IF (!mpfr_nan_p (y) || inexact != 0,
190                   "ERROR: mpfr_set failed to set variable to NaN (3).\n");
191   PRINT_ERROR_IF (s1 != s2,
192                   "ERROR: mpfr_set doesn't preserve the sign bit (3).\n");
193 
194   mpfr_clear_nanflag ();
195   inexact = mpfr_set (x, x, MPFR_RNDN);
196   s2 = mpfr_signbit (x) != 0;
197   PRINT_ERROR_IF (!mpfr_nanflag_p (),
198                   "ERROR: mpfr_set doesn't set Nan flag (4).\n");
199   PRINT_ERROR_IF (!mpfr_nan_p (x) || inexact != 0,
200                   "ERROR: mpfr_set failed to set variable to NaN (4).\n");
201   PRINT_ERROR_IF (s1 != s2,
202                   "ERROR: mpfr_set doesn't preserve the sign bit (4).\n");
203 
204   mpfr_clears (x, y, (mpfr_ptr) 0);
205 }
206 
207 static void
208 check_ternary_value (void)
209 {
210   int p, q, rnd;
211   int inexact, cmp;
212   mpfr_t x, y;
213 
214   mpfr_init (x);
215   mpfr_init (y);
216   for (p=2; p<500; p++)
217     {
218       mpfr_set_prec (x, p);
219       mpfr_urandomb (x, RANDS);
220       if (randlimb () % 2)
221         mpfr_neg (x, x, MPFR_RNDN);
222       for (q=2; q<2*p; q++)
223         {
224           mpfr_set_prec (y, q);
225           for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
226             {
227               if (rnd == MPFR_RNDF) /* the test below makes no sense */
228                 continue;
229               inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd);
230               cmp = mpfr_cmp (y, x);
231               if (((inexact == 0) && (cmp != 0)) ||
232                   ((inexact > 0) && (cmp <= 0)) ||
233                   ((inexact < 0) && (cmp >= 0)))
234                 {
235                   printf ("Wrong ternary value in mpfr_set for %s: expected"
236                           " %d, got %d\n",
237                           mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), cmp,
238                           inexact);
239                   exit (1);
240                 }
241               /* Test mpfr_set function too */
242               inexact = (mpfr_set) (y, x, (mpfr_rnd_t) rnd);
243               cmp = mpfr_cmp (y, x);
244               if (((inexact == 0) && (cmp != 0)) ||
245                   ((inexact > 0) && (cmp <= 0)) ||
246                   ((inexact < 0) && (cmp >= 0)))
247                 {
248                   printf ("Wrong ternary value in mpfr_set(2): expected %d,"
249                           " got %d\n", cmp, inexact);
250                   exit (1);
251                 }
252             }
253         }
254     }
255   mpfr_clear (x);
256   mpfr_clear (y);
257 }
258 
259 #define TEST_FUNCTION mpfr_set
260 #include "tgeneric.c"
261 
262 int
263 main (void)
264 {
265   mpfr_t x, y, z, u;
266   int inexact;
267   mpfr_exp_t emax;
268 
269   tests_start_mpfr ();
270 
271   /* Default : no error */
272   error = 0;
273 
274   /* check prototypes of mpfr_init_set_* */
275   inexact = mpfr_init_set_si (x, -1, MPFR_RNDN);
276   MPFR_ASSERTN (inexact == 0);
277   inexact = mpfr_init_set (y, x, MPFR_RNDN);
278   MPFR_ASSERTN (inexact == 0);
279   inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN);
280   MPFR_ASSERTN (inexact == 0);
281   inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN);
282   MPFR_ASSERTN (inexact == 0);
283 
284   emax = mpfr_get_emax ();
285   set_emax (0);
286   mpfr_set_prec (x, 3);
287   mpfr_set_str_binary (x, "0.111");
288   mpfr_set_prec (y, 2);
289   mpfr_set (y, x, MPFR_RNDU);
290   if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y)))
291     {
292       printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx=");
293       mpfr_dump (x);
294       printf ("y=");
295       mpfr_dump (y);
296       exit (1);
297     }
298 
299   set_emax (emax);
300 
301   mpfr_set_prec (y, 11);
302   mpfr_set_str_binary (y, "0.11111111100E-8");
303   mpfr_set_prec (x, 2);
304   mpfr_set (x, y, MPFR_RNDN);
305   mpfr_set_str_binary (y, "1.0E-8");
306   if (mpfr_cmp (x, y))
307     {
308       printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n");
309       exit (1);
310     }
311 
312   mpfr_clear (x);
313   mpfr_clear (y);
314   mpfr_clear (z);
315   mpfr_clear (u);
316 
317   check_ternary_value ();
318   check_special ();
319   check_neg_special ();
320 
321   test_generic (MPFR_PREC_MIN, 1000, 10);
322 
323   tests_end_mpfr ();
324   return error;
325 }
326