tset.c revision 1.1.1.5 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