xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset.c (revision a8c74629f602faa0ccf8a463757d7baf858bbf3a)
1 /* Test file for mpfr_set.
2 
3 Copyright 2001-2020 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
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 static void
260 test_set_1_2 (void)
261 {
262   mpfr_t u, v, zz, z;
263   int inex;
264 
265   /* (8,16)-bit test */
266   mpfr_inits2 (16, u, v, zz, (mpfr_ptr) 0);
267   mpfr_init2 (z, 8);
268   mpfr_set_str_binary (u, "0.1100001100011010E-1");
269   mpfr_set_str_binary (v, "0.1100010101110010E0");
270   /* u + v = 1.0010011011111111 */
271   inex = mpfr_add (zz, u, v, MPFR_RNDN);
272   MPFR_ASSERTN(inex > 0);
273   mpfr_set_str_binary (u, "1.001001110000000");
274   MPFR_ASSERTN(mpfr_equal_p (zz, u));
275   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
276   /* we should have z = 1.0010011 and inex < 0 */
277   MPFR_ASSERTN(inex < 0);
278   mpfr_set_str_binary (u, "1.0010011");
279   MPFR_ASSERTN(mpfr_equal_p (z, u));
280   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
281 
282   /* (16,32)-bit test:
283    * take for v a random 32-bit number in [1/2,1), here 2859611790/2^32
284    * take for z a random 16-bit number in [1,2), less than 2*v,
285    with last bit 0, here we take z = 40900/2^15
286    * take u = z-v-1/2^16-1/2^32 */
287   mpfr_inits2 (32, u, v, zz, (mpfr_ptr) 0);
288   mpfr_init2 (z, 16);
289   mpfr_set_str_binary (u, "0.10010101000101001100100101110001");
290   mpfr_set_str_binary (v, "0.10101010011100100011011010001110");
291   /* u + v = 1.00111111100001101111111111111111 */
292   inex = mpfr_add (zz, u, v, MPFR_RNDN);
293   MPFR_ASSERTN(inex > 0);
294   mpfr_set_str_binary (u, "1.0011111110000111");
295   MPFR_ASSERTN(mpfr_equal_p (zz, u));
296   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
297   /* we should have z = 1.001111111000011 and inex < 0 */
298   MPFR_ASSERTN(inex < 0);
299   mpfr_set_str_binary (u, "1.001111111000011");
300   MPFR_ASSERTN(mpfr_equal_p (z, u));
301   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
302 
303   /* (32,64)-bit test:
304    * take for v a random 64-bit number in [1/2,1),
305      here v = 13687985014345662879/2^64
306    * take for z a random 32-bit number in [1,2), less than 2*v,
307      with last bit 0, here we take z = 2871078774/2^31
308    * take u = z-v-1/2^32-1/2^64 */
309   mpfr_inits2 (64, u, v, zz, (mpfr_ptr) 0);
310   mpfr_init2 (z, 32);
311   mpfr_set_str_binary (u, "0.10011000010011001110000100010001110010010000111001111110011");
312   mpfr_set_str_binary (v, "0.1011110111110101011111011101100100110110111100011000000110011111");
313   /* u + v = 1.0101011001000010010111101110101011111111111111111111111111111111 */
314   inex = mpfr_add (zz, u, v, MPFR_RNDN);
315   MPFR_ASSERTN(inex > 0);
316   mpfr_set_str_binary (u, "1.01010110010000100101111011101011");
317   MPFR_ASSERTN(mpfr_equal_p (zz, u));
318   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
319   /* we should have z = 1.0101011001000010010111101110101 and inex < 0 */
320   MPFR_ASSERTN(inex < 0);
321   mpfr_set_str_binary (u, "1.0101011001000010010111101110101");
322   MPFR_ASSERTN(mpfr_equal_p (z, u));
323   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
324 
325   /* (64,128)-bit test:
326    * take for v a random 128-bit number in [1/2,1),
327      here v = 322263811942091240216761391118876232409/2^128
328    * take for z a random 64-bit number in [1,2), less than 2*v,
329      with last bit 0, here we take z = 16440347967874738276/2^63
330    * take u = z-v-1/2^64-1/2^128 */
331   mpfr_inits2 (128, u, v, zz, (mpfr_ptr) 0);
332   mpfr_init2 (z, 64);
333   mpfr_set_str_binary (u, "0.1101010111011101111100100001011111111000010011011001000101111010110101101101011011100110101001010001101011011110101101010010011");
334   mpfr_set_str_binary (v, "0.11110010011100011100000010100110100010011010110010111111010011000010100100101001000110010101101011100101001000010100101011011001");
335   inex = mpfr_add (zz, u, v, MPFR_RNDN);
336   MPFR_ASSERTN(inex > 0);
337   mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000111");
338   MPFR_ASSERTN(mpfr_equal_p (zz, u));
339   inex = mpfr_set_1_2 (z, zz, MPFR_RNDN, inex);
340   MPFR_ASSERTN(inex < 0);
341   mpfr_set_str_binary (u, "1.1100100001001111101100101011111010000001111110100101000011000110");
342   MPFR_ASSERTN(mpfr_equal_p (z, u));
343   mpfr_clears (u, v, zz, z, (mpfr_ptr) 0);
344 }
345 
346 #define TEST_FUNCTION mpfr_set
347 #include "tgeneric.c"
348 
349 int
350 main (void)
351 {
352   mpfr_t x, y, z, u;
353   int inexact;
354   mpfr_exp_t emax;
355 
356   tests_start_mpfr ();
357 
358   test_set_1_2 ();
359 
360   /* Default : no error */
361   error = 0;
362 
363   /* check prototypes of mpfr_init_set_* */
364   inexact = mpfr_init_set_si (x, -1, MPFR_RNDN);
365   MPFR_ASSERTN (inexact == 0);
366   inexact = mpfr_init_set (y, x, MPFR_RNDN);
367   MPFR_ASSERTN (inexact == 0);
368   inexact = mpfr_init_set_ui (z, 1, MPFR_RNDN);
369   MPFR_ASSERTN (inexact == 0);
370   inexact = mpfr_init_set_d (u, 1.0, MPFR_RNDN);
371   MPFR_ASSERTN (inexact == 0);
372 
373   emax = mpfr_get_emax ();
374   set_emax (0);
375   mpfr_set_prec (x, 3);
376   mpfr_set_str_binary (x, "0.111");
377   mpfr_set_prec (y, 2);
378   mpfr_set (y, x, MPFR_RNDU);
379   if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y)))
380     {
381       printf ("Error for y=x=0.111 with px=3, py=2 and emax=0\nx=");
382       mpfr_dump (x);
383       printf ("y=");
384       mpfr_dump (y);
385       exit (1);
386     }
387 
388   set_emax (emax);
389 
390   mpfr_set_prec (y, 11);
391   mpfr_set_str_binary (y, "0.11111111100E-8");
392   mpfr_set_prec (x, 2);
393   mpfr_set (x, y, MPFR_RNDN);
394   mpfr_set_str_binary (y, "1.0E-8");
395   if (mpfr_cmp (x, y))
396     {
397       printf ("Error for y=0.11111111100E-8, prec=2, rnd=MPFR_RNDN\n");
398       exit (1);
399     }
400 
401   mpfr_clear (x);
402   mpfr_clear (y);
403   mpfr_clear (z);
404   mpfr_clear (u);
405 
406   check_ternary_value ();
407   check_special ();
408   check_neg_special ();
409 
410   test_generic (MPFR_PREC_MIN, 1000, 10);
411 
412   tests_end_mpfr ();
413   return error;
414 }
415