xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_set.
2 
3 Copyright 2001-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 #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
check_neg_special(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
check_special(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
check_ternary_value(void)208 check_ternary_value (void)
209 {
210   int k, 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 (RAND_BOOL ())
221         mpfr_neg (x, x, MPFR_RNDN);
222       for (q=2; q<2*p; q++)
223         {
224           mpfr_set_prec (y, q);
225           RND_LOOP (rnd)
226             {
227               if (rnd == MPFR_RNDF) /* the test below makes no sense */
228                 continue;
229               for (k = 0; k < 3; k++)
230                 {
231                   int a = 0, b = 0, c = 0;
232 
233                   switch (k)
234                     {
235                     case 0:
236                       inexact = mpfr_set (y, x, (mpfr_rnd_t) rnd);
237                       break;
238                     case 1:
239                       inexact = (mpfr_set) (y, x, (mpfr_rnd_t) rnd);
240                       break;
241                     case 2:
242 #ifdef IGNORE_CPP_COMPAT
243 #pragma GCC diagnostic push
244 #pragma GCC diagnostic ignored "-Wc++-compat"
245 #endif
246                       inexact = mpfr_set ((a++, VOIDP_CAST(y)),
247                                           (b++, VOIDP_CAST(x)),
248                                           (c++, (mpfr_rnd_t) rnd));
249 #ifdef IGNORE_CPP_COMPAT
250 #pragma GCC diagnostic pop
251 #endif
252                       MPFR_ASSERTN (a == 1);
253                       MPFR_ASSERTN (b == 1);
254                       MPFR_ASSERTN (c == 1);
255                       break;
256                     }
257                   cmp = mpfr_cmp (y, x);
258                   if (((inexact == 0) && (cmp != 0)) ||
259                       ((inexact > 0) && (cmp <= 0)) ||
260                       ((inexact < 0) && (cmp >= 0)))
261                     {
262                       printf ("Wrong ternary value in mpfr_set for %s (%d):"
263                               " expected %d, got %d\n",
264                               mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
265                               k, cmp, inexact);
266                       exit (1);
267                     }
268                 }
269             }
270         }
271     }
272   mpfr_clear (x);
273   mpfr_clear (y);
274 }
275 
276 static void
test_set_1_2(void)277 test_set_1_2 (void)
278 {
279   mpfr_t u, v, zz, z;
280   int inex;
281 
282   /* (8,16)-bit test */
283   mpfr_inits2 (16, u, v, zz, (mpfr_ptr) 0);
284   mpfr_init2 (z, 8);
285   mpfr_set_str_binary (u, "0.1100001100011010E-1");
286   mpfr_set_str_binary (v, "0.1100010101110010E0");
287   /* u + v = 1.0010011011111111 */
288   inex = mpfr_add (zz, u, v, MPFR_RNDN);
289   MPFR_ASSERTN(inex > 0);
290   mpfr_set_str_binary (u, "1.001001110000000");
291   MPFR_ASSERTN(mpfr_equal_p (zz, u));
292   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
293   /* we should have z = 1.0010011 and inex < 0 */
294   MPFR_ASSERTN(inex < 0);
295   mpfr_set_str_binary (u, "1.0010011");
296   MPFR_ASSERTN(mpfr_equal_p (z, u));
297   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
298 
299   /* (16,32)-bit test:
300    * take for v a random 32-bit number in [1/2,1), here 2859611790/2^32
301    * take for z a random 16-bit number in [1,2), less than 2*v,
302    with last bit 0, here we take z = 40900/2^15
303    * take u = z-v-1/2^16-1/2^32 */
304   mpfr_inits2 (32, u, v, zz, (mpfr_ptr) 0);
305   mpfr_init2 (z, 16);
306   mpfr_set_str_binary (u, "0.10010101000101001100100101110001");
307   mpfr_set_str_binary (v, "0.10101010011100100011011010001110");
308   /* u + v = 1.00111111100001101111111111111111 */
309   inex = mpfr_add (zz, u, v, MPFR_RNDN);
310   MPFR_ASSERTN(inex > 0);
311   mpfr_set_str_binary (u, "1.0011111110000111");
312   MPFR_ASSERTN(mpfr_equal_p (zz, u));
313   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
314   /* we should have z = 1.001111111000011 and inex < 0 */
315   MPFR_ASSERTN(inex < 0);
316   mpfr_set_str_binary (u, "1.001111111000011");
317   MPFR_ASSERTN(mpfr_equal_p (z, u));
318   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
319 
320   /* (32,64)-bit test:
321    * take for v a random 64-bit number in [1/2,1),
322      here v = 13687985014345662879/2^64
323    * take for z a random 32-bit number in [1,2), less than 2*v,
324      with last bit 0, here we take z = 2871078774/2^31
325    * take u = z-v-1/2^32-1/2^64 */
326   mpfr_inits2 (64, u, v, zz, (mpfr_ptr) 0);
327   mpfr_init2 (z, 32);
328   mpfr_set_str_binary (u, "0.10011000010011001110000100010001110010010000111001111110011");
329   mpfr_set_str_binary (v, "0.1011110111110101011111011101100100110110111100011000000110011111");
330   /* u + v = 1.0101011001000010010111101110101011111111111111111111111111111111 */
331   inex = mpfr_add (zz, u, v, MPFR_RNDN);
332   MPFR_ASSERTN(inex > 0);
333   mpfr_set_str_binary (u, "1.01010110010000100101111011101011");
334   MPFR_ASSERTN(mpfr_equal_p (zz, u));
335   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
336   /* we should have z = 1.0101011001000010010111101110101 and inex < 0 */
337   MPFR_ASSERTN(inex < 0);
338   mpfr_set_str_binary (u, "1.0101011001000010010111101110101");
339   MPFR_ASSERTN(mpfr_equal_p (z, u));
340   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
341 
342   /* (64,128)-bit test:
343    * take for v a random 128-bit number in [1/2,1),
344      here v = 322263811942091240216761391118876232409/2^128
345    * take for z a random 64-bit number in [1,2), less than 2*v,
346      with last bit 0, here we take z = 16440347967874738276/2^63
347    * take u = z-v-1/2^64-1/2^128 */
348   mpfr_inits2 (128, u, v, zz, (mpfr_ptr) 0);
349   mpfr_init2 (z, 64);
350   mpfr_set_str_binary (u, "0.1101010111011101111100100001011111111000010011011001000101111010110101101101011011100110101001010001101011011110101101010010011");
351   mpfr_set_str_binary (v, "0.11110010011100011100000010100110100010011010110010111111010011000010100100101001000110010101101011100101001000010100101011011001");
352   inex = mpfr_add (zz, u, v, MPFR_RNDN);
353   MPFR_ASSERTN(inex > 0);
354   mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000111");
355   MPFR_ASSERTN(mpfr_equal_p (zz, u));
356   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
357   MPFR_ASSERTN(inex < 0);
358   mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000110");
359   MPFR_ASSERTN(mpfr_equal_p (z, u));
360   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
361 }
362 
363 #define TEST_FUNCTION mpfr_set
364 #include "tgeneric.c"
365 
366 int
main(void)367 main (void)
368 {
369   mpfr_t x, y, z, u;
370   int inexact;
371   mpfr_exp_t emax;
372 
373   tests_start_mpfr ();
374 
375   test_set_1_2 ();
376 
377   /* Default : no error */
378   error = 0;
379 
380   /* check prototypes of mpfr_init_set_* */
381   inexact = mpfr_init_set_si (x, -1, MPFR_RNDN);
382   MPFR_ASSERTN (inexact == 0);
383   inexact = mpfr_init_set (y, x, MPFR_RNDN);
384   MPFR_ASSERTN (inexact == 0);
385   inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN);
386   MPFR_ASSERTN (inexact == 0);
387   inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN);
388   MPFR_ASSERTN (inexact == 0);
389 
390   emax = mpfr_get_emax ();
391   set_emax (0);
392   mpfr_set_prec (x, 3);
393   mpfr_set_str_binary (x, "0.111");
394   mpfr_set_prec (y, 2);
395   mpfr_set (y, x, MPFR_RNDU);
396   if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y)))
397     {
398       printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx=");
399       mpfr_dump (x);
400       printf ("y=");
401       mpfr_dump (y);
402       exit (1);
403     }
404 
405   set_emax (emax);
406 
407   mpfr_set_prec (y, 11);
408   mpfr_set_str_binary (y, "0.11111111100E-8");
409   mpfr_set_prec (x, 2);
410   mpfr_set (x, y, MPFR_RNDN);
411   mpfr_set_str_binary (y, "1.0E-8");
412   if (mpfr_cmp (x, y))
413     {
414       printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n");
415       exit (1);
416     }
417 
418   mpfr_clear (x);
419   mpfr_clear (y);
420   mpfr_clear (z);
421   mpfr_clear (u);
422 
423   check_ternary_value ();
424   check_special ();
425   check_neg_special ();
426 
427   test_generic (MPFR_PREC_MIN, 1000, 10);
428 
429   tests_end_mpfr ();
430   return error;
431 }
432