1/* Test file for mpfr_set_si and mpfr_set_ui.
2
3Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4Contributed by the AriC and Caramel projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <limits.h>
26
27#include "mpfr-test.h"
28
29#define ERROR(str) {printf("Error for "str"\n"); exit(1);}
30
31static void
32test_2exp (void)
33{
34  mpfr_t x;
35  int res;
36
37  mpfr_init2 (x, 32);
38
39  mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
40  if (mpfr_cmp_ui(x, 1))
41    ERROR("(1U,0)");
42
43  mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
44  if (mpfr_cmp_ui(x, 1))
45    ERROR("(1024U,-10)");
46
47  mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
48  if (mpfr_cmp_ui(x, 1024*1024))
49    ERROR("(1024U,+10)");
50
51  mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
52  if (mpfr_cmp_si(x, -1024))
53    ERROR("(1M,-10)");
54
55  mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
56  if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN))
57    ERROR("(x92345678U,+16)");
58
59  mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
60  if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN))
61    ERROR("(-x1ABCDEF0,-256)");
62
63  mpfr_set_prec (x, 2);
64  res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
65  if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
66    ERROR ("Prec 2 + si_2exp");
67
68  res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
69  if (mpfr_cmp_ui (x, 1<<13) || res <= 0)
70    ERROR ("Prec 2 + ui_2exp");
71
72  mpfr_clear_flags ();
73  mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
74  if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
75    ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
76  if (!mpfr_overflow_p ())
77    ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");
78
79  mpfr_clear_flags ();
80  mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
81  if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
82    ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
83  if (!mpfr_overflow_p ())
84    ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");
85
86  mpfr_clear_flags ();
87  mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
88  if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
89    ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
90  if (!mpfr_overflow_p ())
91    ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");
92
93  mpfr_clear (x);
94}
95
96static void
97test_macros (void)
98{
99  mpfr_t x[3];
100  mpfr_ptr p;
101  int r;
102
103  mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
104  p = x[0];
105  r = 0;
106  mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++);
107  if (p != x[1] || r != 1)
108    {
109      printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), "
110              "r = %d (expecting 1)\n", (int) (p - x[0]), r);
111      exit (1);
112    }
113  p = x[0];
114  r = 0;
115  mpfr_set_si (p++, 0, (mpfr_rnd_t) r++);
116  if (p != x[1] || r != 1)
117    {
118      printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), "
119              "r = %d (expecting 1)\n", (int) (p - x[0]), r);
120      exit (1);
121    }
122  mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
123}
124
125static void
126test_macros_keyword (void)
127{
128  mpfr_t x;
129  unsigned long i;
130
131  mpfr_init2 (x, 64);
132#define MKN 0x1000000
133#define long short
134  mpfr_set_ui (x, MKN, MPFR_RNDN);
135#undef long
136  i = mpfr_get_ui (x, MPFR_RNDN);
137  if (i != MKN)
138    {
139      printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n",
140              (unsigned long) MKN, i);
141      exit (1);
142    }
143  mpfr_clear (x);
144}
145
146/* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
147   have all tests examine the bits in mpfr_t for what should come out.  */
148
149int
150main (int argc, char *argv[])
151{
152  mpfr_t x;
153  long k, z, d, N;
154  unsigned long zl, dl;
155  int inex;
156  int r;
157  mpfr_exp_t emin, emax;
158  int flag;
159
160  tests_start_mpfr ();
161
162  mpfr_init2 (x, 100);
163
164  N = (argc==1) ? 100000 : atol (argv[1]);
165
166  for (k = 1; k <= N; k++)
167    {
168      z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
169      inex = mpfr_set_si (x, z, MPFR_RNDZ);
170      d = mpfr_get_si (x, MPFR_RNDZ);
171      if (d != z)
172        {
173          printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
174          exit (1);
175        }
176      if (inex)
177        {
178          printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
179                  z, inex);
180          exit (1);
181        }
182    }
183
184  for (k = 1; k <= N; k++)
185    {
186      zl = randlimb ();
187      inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
188      dl = mpfr_get_ui (x, MPFR_RNDZ);
189      if (dl != zl)
190        {
191          printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
192          exit (1);
193        }
194      if (inex)
195        {
196          printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
197                  zl, inex);
198          exit (1);
199        }
200    }
201
202  mpfr_set_prec (x, 2);
203  if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
204    {
205      printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
206      exit (1);
207    }
208
209  mpfr_set_prec (x, 2);
210  if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
211    {
212      printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
213      exit (1);
214    }
215
216  mpfr_set_prec (x, 3);
217  inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
218  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
219      || inex >= 0)
220    {
221      printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
222      mpfr_print_binary (x);
223      puts ("");
224      exit (1);
225    }
226  inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
227  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
228      || inex >= 0)
229    {
230      printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
231      mpfr_print_binary (x);
232      puts ("");
233      exit (1);
234    }
235
236  mpfr_set_prec (x, 2);
237  inex = mpfr_set_si (x, 33096, MPFR_RNDU);
238  if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
239    {
240      printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
241              mpfr_get_si (x, MPFR_RNDZ), inex);
242      exit (1);
243    }
244  inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
245  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
246    {
247      printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
248              mpfr_get_si (x, MPFR_RNDZ), inex);
249      exit (1);
250    }
251  /* Also test the mpfr_set_ui function (instead of macro). */
252  inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
253  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
254    {
255      printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
256              mpfr_get_si (x, MPFR_RNDZ), inex);
257      exit (1);
258    }
259
260  for (r = 0 ; r < MPFR_RND_MAX ; r++)
261    {
262      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
263      mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
264      if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
265        {
266          printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
267                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
268          exit (1);
269        }
270
271      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
272      mpfr_set_si (x, 0, (mpfr_rnd_t) r);
273      if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
274        {
275          printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
276                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
277          exit (1);
278        }
279    }
280
281  /* check potential bug in case mp_limb_t is unsigned */
282  emax = mpfr_get_emax ();
283  set_emax (0);
284  mpfr_set_si (x, -1, MPFR_RNDN);
285  if (mpfr_sgn (x) >= 0)
286    {
287      printf ("mpfr_set_si (x, -1) fails\n");
288      exit (1);
289    }
290  set_emax (emax);
291
292  emax = mpfr_get_emax ();
293  set_emax (5);
294  mpfr_set_prec (x, 2);
295  mpfr_set_si (x, -31, MPFR_RNDN);
296  if (mpfr_sgn (x) >= 0)
297    {
298      printf ("mpfr_set_si (x, -31) fails\n");
299      exit (1);
300    }
301  set_emax (emax);
302
303  /* test for get_ui */
304  mpfr_set_ui (x, 0, MPFR_RNDN);
305  MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
306  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
307  mpfr_nextabove (x);
308  mpfr_get_ui (x, MPFR_RNDU);
309
310  /* another test for get_ui */
311  mpfr_set_prec (x, 10);
312  mpfr_set_str_binary (x, "10.101");
313  dl = mpfr_get_ui (x, MPFR_RNDN);
314  MPFR_ASSERTN (dl == 3);
315
316  mpfr_set_str_binary (x, "-1.0");
317  mpfr_get_ui (x, MPFR_RNDN);
318
319  mpfr_set_str_binary (x, "0.1");
320  dl = mpfr_get_ui (x, MPFR_RNDN);
321  MPFR_ASSERTN (dl == 0);
322  dl = mpfr_get_ui (x, MPFR_RNDZ);
323  MPFR_ASSERTN (dl == 0);
324  dl = mpfr_get_ui (x, MPFR_RNDD);
325  MPFR_ASSERTN (dl == 0);
326  dl = mpfr_get_ui (x, MPFR_RNDU);
327  MPFR_ASSERTN (dl == 1);
328
329  /* coverage tests */
330  mpfr_set_prec (x, 2);
331  mpfr_set_si (x, -7, MPFR_RNDD);
332  MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
333  mpfr_set_prec (x, 2);
334  mpfr_set_ui (x, 7, MPFR_RNDU);
335  MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
336  emax = mpfr_get_emax ();
337  set_emax (3);
338  mpfr_set_ui (x, 7, MPFR_RNDU);
339  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
340  set_emax (1);
341  MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
342  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
343  set_emax (emax);
344  mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
345  MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
346  MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
347
348  /* Test for ERANGE flag + correct behaviour if overflow */
349  mpfr_set_prec (x, 256);
350  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
351  mpfr_clear_erangeflag ();
352  dl = mpfr_get_ui (x, MPFR_RNDN);
353  if (dl != ULONG_MAX || mpfr_erangeflag_p ())
354    {
355      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
356      exit (1);
357    }
358  mpfr_add_ui (x, x, 1, MPFR_RNDN);
359  dl = mpfr_get_ui (x, MPFR_RNDN);
360  if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
361    {
362      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
363      exit (1);
364    }
365  mpfr_set_si (x, -1, MPFR_RNDN);
366  mpfr_clear_erangeflag ();
367  dl = mpfr_get_ui (x, MPFR_RNDN);
368  if (dl != 0 || !mpfr_erangeflag_p ())
369    {
370      printf ("ERROR for get_ui + ERANGE + -1 \n");
371      exit (1);
372    }
373  mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
374  mpfr_clear_erangeflag ();
375  d = mpfr_get_si (x, MPFR_RNDN);
376  if (d != LONG_MAX || mpfr_erangeflag_p ())
377    {
378      printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
379      exit (1);
380    }
381  mpfr_add_ui (x, x, 1, MPFR_RNDN);
382  d = mpfr_get_si (x, MPFR_RNDN);
383  if (d != LONG_MAX || !mpfr_erangeflag_p ())
384    {
385      printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
386      exit (1);
387    }
388  mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
389  mpfr_clear_erangeflag ();
390  d = mpfr_get_si (x, MPFR_RNDN);
391  if (d != LONG_MIN || mpfr_erangeflag_p ())
392    {
393      printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
394      exit (1);
395    }
396  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
397  d = mpfr_get_si (x, MPFR_RNDN);
398  if (d != LONG_MIN || !mpfr_erangeflag_p ())
399    {
400      printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
401      exit (1);
402    }
403
404  mpfr_set_nan (x);
405  mpfr_clear_erangeflag ();
406  d = mpfr_get_ui (x, MPFR_RNDN);
407  if (d != 0 || !mpfr_erangeflag_p ())
408    {
409      printf ("ERROR for get_ui + NaN\n");
410      exit (1);
411    }
412  mpfr_clear_erangeflag ();
413  d = mpfr_get_si (x, MPFR_RNDN);
414  if (d != 0 || !mpfr_erangeflag_p ())
415    {
416      printf ("ERROR for get_si + NaN\n");
417      exit (1);
418    }
419
420  emin = mpfr_get_emin ();
421  mpfr_set_prec (x, 2);
422
423  mpfr_set_emin (4);
424  mpfr_clear_flags ();
425  mpfr_set_ui (x, 7, MPFR_RNDU);
426  flag = mpfr_underflow_p ();
427  mpfr_set_emin (emin);
428  if (mpfr_cmp_ui (x, 8) != 0)
429    {
430      printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
431      exit (1);
432    }
433  if (flag)
434    {
435      printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
436              "with prec = 2, emin = 4\n");
437      exit (1);
438    }
439
440  mpfr_set_emin (4);
441  mpfr_clear_flags ();
442  mpfr_set_si (x, -7, MPFR_RNDD);
443  flag = mpfr_underflow_p ();
444  mpfr_set_emin (emin);
445  if (mpfr_cmp_si (x, -8) != 0)
446    {
447      printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
448      exit (1);
449    }
450  if (flag)
451    {
452      printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
453              "with prec = 2, emin = 4\n");
454      exit (1);
455    }
456
457  mpfr_clear (x);
458
459  test_2exp ();
460  test_macros ();
461  test_macros_keyword ();
462  tests_end_mpfr ();
463  return 0;
464}
465