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 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao 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
125/* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
126   have all tests examine the bits in mpfr_t for what should come out.  */
127
128int
129main (int argc, char *argv[])
130{
131  mpfr_t x;
132  long k, z, d, N;
133  unsigned long zl, dl;
134  int inex;
135  int r;
136  mpfr_exp_t emin, emax;
137  int flag;
138
139  tests_start_mpfr ();
140
141  mpfr_init2 (x, 100);
142
143  N = (argc==1) ? 100000 : atol (argv[1]);
144
145  for (k = 1; k <= N; k++)
146    {
147      z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
148      inex = mpfr_set_si (x, z, MPFR_RNDZ);
149      d = mpfr_get_si (x, MPFR_RNDZ);
150      if (d != z)
151        {
152          printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
153          exit (1);
154        }
155      if (inex)
156        {
157          printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
158                  z, inex);
159          exit (1);
160        }
161    }
162
163  for (k = 1; k <= N; k++)
164    {
165      zl = randlimb ();
166      inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
167      dl = mpfr_get_ui (x, MPFR_RNDZ);
168      if (dl != zl)
169        {
170          printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
171          exit (1);
172        }
173      if (inex)
174        {
175          printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
176                  zl, inex);
177          exit (1);
178        }
179    }
180
181  mpfr_set_prec (x, 2);
182  if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
183    {
184      printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
185      exit (1);
186    }
187
188  mpfr_set_prec (x, 2);
189  if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
190    {
191      printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
192      exit (1);
193    }
194
195  mpfr_set_prec (x, 3);
196  inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
197  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
198      || inex >= 0)
199    {
200      printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
201      mpfr_print_binary (x);
202      puts ("");
203      exit (1);
204    }
205  inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
206  if (MPFR_MANT(x)[0] != ((mp_limb_t)1 << (mp_bits_per_limb-1))
207      || inex >= 0)
208    {
209      printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
210      mpfr_print_binary (x);
211      puts ("");
212      exit (1);
213    }
214
215  mpfr_set_prec (x, 2);
216  inex = mpfr_set_si (x, 33096, MPFR_RNDU);
217  if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
218    {
219      printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
220              mpfr_get_si (x, MPFR_RNDZ), inex);
221      exit (1);
222    }
223  inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
224  if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
225    {
226      printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
227              mpfr_get_si (x, MPFR_RNDZ), inex);
228      exit (1);
229    }
230
231  for (r = 0 ; r < MPFR_RND_MAX ; r++)
232    {
233      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
234      mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
235      if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
236        {
237          printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
238                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
239          exit (1);
240        }
241
242      mpfr_set_si (x, -1, (mpfr_rnd_t) r);
243      mpfr_set_si (x, 0, (mpfr_rnd_t) r);
244      if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
245        {
246          printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
247                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
248          exit (1);
249        }
250    }
251
252  /* check potential bug in case mp_limb_t is unsigned */
253  emax = mpfr_get_emax ();
254  set_emax (0);
255  mpfr_set_si (x, -1, MPFR_RNDN);
256  if (mpfr_sgn (x) >= 0)
257    {
258      printf ("mpfr_set_si (x, -1) fails\n");
259      exit (1);
260    }
261  set_emax (emax);
262
263  emax = mpfr_get_emax ();
264  set_emax (5);
265  mpfr_set_prec (x, 2);
266  mpfr_set_si (x, -31, MPFR_RNDN);
267  if (mpfr_sgn (x) >= 0)
268    {
269      printf ("mpfr_set_si (x, -31) fails\n");
270      exit (1);
271    }
272  set_emax (emax);
273
274  /* test for get_ui */
275  mpfr_set_ui (x, 0, MPFR_RNDN);
276  MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
277  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
278  mpfr_nextabove (x);
279  mpfr_get_ui (x, MPFR_RNDU);
280
281  /* another test for get_ui */
282  mpfr_set_prec (x, 10);
283  mpfr_set_str_binary (x, "10.101");
284  dl = mpfr_get_ui (x, MPFR_RNDN);
285  MPFR_ASSERTN (dl == 3);
286
287  mpfr_set_str_binary (x, "-1.0");
288  mpfr_get_ui (x, MPFR_RNDN);
289
290  mpfr_set_str_binary (x, "0.1");
291  dl = mpfr_get_ui (x, MPFR_RNDN);
292  MPFR_ASSERTN (dl == 0);
293  dl = mpfr_get_ui (x, MPFR_RNDZ);
294  MPFR_ASSERTN (dl == 0);
295  dl = mpfr_get_ui (x, MPFR_RNDD);
296  MPFR_ASSERTN (dl == 0);
297  dl = mpfr_get_ui (x, MPFR_RNDU);
298  MPFR_ASSERTN (dl == 1);
299
300  /* coverage tests */
301  mpfr_set_prec (x, 2);
302  mpfr_set_si (x, -7, MPFR_RNDD);
303  MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
304  mpfr_set_prec (x, 2);
305  mpfr_set_ui (x, 7, MPFR_RNDU);
306  MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
307  emax = mpfr_get_emax ();
308  set_emax (3);
309  mpfr_set_ui (x, 7, MPFR_RNDU);
310  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
311  set_emax (1);
312  MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
313  MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
314  set_emax (emax);
315  mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
316  MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
317  MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
318
319  /* Test for ERANGE flag + correct behaviour if overflow */
320  mpfr_set_prec (x, 256);
321  mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
322  mpfr_clear_erangeflag ();
323  dl = mpfr_get_ui (x, MPFR_RNDN);
324  if (dl != ULONG_MAX || mpfr_erangeflag_p ())
325    {
326      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
327      exit (1);
328    }
329  mpfr_add_ui (x, x, 1, MPFR_RNDN);
330  dl = mpfr_get_ui (x, MPFR_RNDN);
331  if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
332    {
333      printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
334      exit (1);
335    }
336  mpfr_set_si (x, -1, MPFR_RNDN);
337  mpfr_clear_erangeflag ();
338  dl = mpfr_get_ui (x, MPFR_RNDN);
339  if (dl != 0 || !mpfr_erangeflag_p ())
340    {
341      printf ("ERROR for get_ui + ERANGE + -1 \n");
342      exit (1);
343    }
344  mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
345  mpfr_clear_erangeflag ();
346  d = mpfr_get_si (x, MPFR_RNDN);
347  if (d != LONG_MAX || mpfr_erangeflag_p ())
348    {
349      printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
350      exit (1);
351    }
352  mpfr_add_ui (x, x, 1, MPFR_RNDN);
353  d = mpfr_get_si (x, MPFR_RNDN);
354  if (d != LONG_MAX || !mpfr_erangeflag_p ())
355    {
356      printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
357      exit (1);
358    }
359  mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
360  mpfr_clear_erangeflag ();
361  d = mpfr_get_si (x, MPFR_RNDN);
362  if (d != LONG_MIN || mpfr_erangeflag_p ())
363    {
364      printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
365      exit (1);
366    }
367  mpfr_sub_ui (x, x, 1, MPFR_RNDN);
368  d = mpfr_get_si (x, MPFR_RNDN);
369  if (d != LONG_MIN || !mpfr_erangeflag_p ())
370    {
371      printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
372      exit (1);
373    }
374
375  mpfr_set_nan (x);
376  mpfr_clear_erangeflag ();
377  d = mpfr_get_ui (x, MPFR_RNDN);
378  if (d != 0 || !mpfr_erangeflag_p ())
379    {
380      printf ("ERROR for get_ui + NaN\n");
381      exit (1);
382    }
383  mpfr_clear_erangeflag ();
384  d = mpfr_get_si (x, MPFR_RNDN);
385  if (d != 0 || !mpfr_erangeflag_p ())
386    {
387      printf ("ERROR for get_si + NaN\n");
388      exit (1);
389    }
390
391  emin = mpfr_get_emin ();
392  mpfr_set_prec (x, 2);
393
394  mpfr_set_emin (4);
395  mpfr_clear_flags ();
396  mpfr_set_ui (x, 7, MPFR_RNDU);
397  flag = mpfr_underflow_p ();
398  mpfr_set_emin (emin);
399  if (mpfr_cmp_ui (x, 8) != 0)
400    {
401      printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
402      exit (1);
403    }
404  if (flag)
405    {
406      printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
407              "with prec = 2, emin = 4\n");
408      exit (1);
409    }
410
411  mpfr_set_emin (4);
412  mpfr_clear_flags ();
413  mpfr_set_si (x, -7, MPFR_RNDD);
414  flag = mpfr_underflow_p ();
415  mpfr_set_emin (emin);
416  if (mpfr_cmp_si (x, -8) != 0)
417    {
418      printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
419      exit (1);
420    }
421  if (flag)
422    {
423      printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
424              "with prec = 2, emin = 4\n");
425      exit (1);
426    }
427
428  mpfr_clear (x);
429
430  test_2exp ();
431  test_macros ();
432  tests_end_mpfr ();
433  return 0;
434}
435