xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_si.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_set_si, mpfr_set_ui, mpfr_get_si and mpfr_get_ui.
2 
3 Copyright 1999, 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 #define PRINT_ERROR(str) \
26   do { printf ("Error for %s\n", str); exit (1); } while (0)
27 
28 static void
test_2exp(void)29 test_2exp (void)
30 {
31   mpfr_t x;
32   int res;
33 
34   mpfr_init2 (x, 32);
35 
36   mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
37   if (mpfr_cmp_ui (x, 1) != 0)
38     PRINT_ERROR ("(1U,0)");
39 
40   mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
41   if (mpfr_cmp_ui(x, 1) != 0)
42     PRINT_ERROR ("(1024U,-10)");
43 
44   mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
45   if (mpfr_cmp_ui (x, 1024 * 1024) != 0)
46     PRINT_ERROR ("(1024U,+10)");
47 
48   mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
49   if (mpfr_cmp_si (x, -1024) != 0)
50     PRINT_ERROR ("(1M,-10)");
51 
52   mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
53   if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN) != 0)
54     PRINT_ERROR ("(x92345678U,+16)");
55 
56   mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
57   if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN) != 0)
58     PRINT_ERROR ("(-x1ABCDEF0,-256)");
59 
60   mpfr_set_prec (x, 2);
61   res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
62   if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
63     PRINT_ERROR ("Prec 2 + si_2exp");
64 
65   res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
66   if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
67     PRINT_ERROR ("Prec 2 + ui_2exp");
68 
69   mpfr_clear_flags ();
70   mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
71   if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
72     PRINT_ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
73   if (!mpfr_overflow_p ())
74     PRINT_ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");
75 
76   mpfr_clear_flags ();
77   mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
78   if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
79     PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
80   if (!mpfr_overflow_p ())
81     PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");
82 
83   mpfr_clear_flags ();
84   mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
85   if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
86     PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
87   if (!mpfr_overflow_p ())
88     PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");
89 
90   mpfr_clear (x);
91 }
92 
93 #define REXP 1024
94 
95 static void
test_2exp_extreme_aux(void)96 test_2exp_extreme_aux (void)
97 {
98   mpfr_t x1, x2, y;
99   mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
100     { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
101   mpfr_flags_t flags1, flags2;
102   int i, j, rnd, inex1, inex2;
103   char s;
104 
105   ep[0] = MPFR_EXP_MIN;
106   for (i = 0; i < numberof(eb); i++)
107     for (j = 0; j < 8; j++)
108       ep[1 + 8 * i + j] = eb[i] - j;
109 
110   mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
111   mpfr_init2 (y, 32);
112 
113   for (i = 0; i < numberof(ep); i++)
114     for (j = -31; j <= 31; j++)
115       RND_LOOP_NO_RNDF (rnd)
116         {
117           int sign = j < 0 ? -1 : 1;
118 
119           /* Compute the expected value, inex and flags */
120           inex1 = mpfr_set_si (y, j, MPFR_RNDN);
121           MPFR_ASSERTN (inex1 == 0);
122           inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
123           /* x1 is the rounded value and inex1 the ternary value,
124              assuming that the exponent argument is 0 (this is the
125              rounded significand of the final result, assuming an
126              unbounded exponent range). The multiplication by a
127              power of 2 is exact, unless underflow/overflow occurs.
128              The tests on the exponent below avoid integer overflows
129              (ep[i] may take extreme values). */
130           mpfr_clear_flags ();
131           if (j == 0)
132             goto zero;
133           e = MPFR_GET_EXP (x1);
134           if (ep[i] < __gmpfr_emin - e)  /* underflow */
135             {
136               mpfr_rnd_t r =
137                 (rnd == MPFR_RNDN &&
138                  (ep[i] < __gmpfr_emin - MPFR_GET_EXP (y) - 1 ||
139                   IS_POW2 (sign * j))) ?
140                 MPFR_RNDZ : (mpfr_rnd_t) rnd;
141               inex1 = mpfr_underflow (x1, r, sign);
142               flags1 = __gmpfr_flags;
143             }
144           else if (ep[i] > __gmpfr_emax - e)  /* overflow */
145             {
146               inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
147               flags1 = __gmpfr_flags;
148             }
149           else
150             {
151               mpfr_set_exp (x1, ep[i] + e);
152             zero:
153               flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
154             }
155 
156           /* Test mpfr_set_si_2exp */
157           mpfr_clear_flags ();
158           inex2 = mpfr_set_si_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
159           flags2 = __gmpfr_flags;
160 
161           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
162                  mpfr_equal_p (x1, x2)))
163             {
164               s = 's';
165               goto err_extreme;
166             }
167 
168           if (j < 0)
169             continue;
170 
171           /* Test mpfr_set_ui_2exp */
172           mpfr_clear_flags ();
173           inex2 = mpfr_set_ui_2exp (x2, j, ep[i], (mpfr_rnd_t) rnd);
174           flags2 = __gmpfr_flags;
175 
176           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
177                  mpfr_equal_p (x1, x2)))
178             {
179               s = 'u';
180             err_extreme:
181               printf ("Error in extreme mpfr_set_%ci_2exp for i=%d j=%d %s\n",
182                       s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
183               printf ("emin=%" MPFR_EXP_FSPEC "d "
184                       "emax=%" MPFR_EXP_FSPEC "d\n",
185                       (mpfr_eexp_t) __gmpfr_emin,
186                       (mpfr_eexp_t) __gmpfr_emax);
187               printf ("ep[%d] = %" MPFR_EXP_FSPEC "d\n",
188                       i, (mpfr_eexp_t) ep[i]);
189               printf ("Expected ");
190               mpfr_dump (x1);
191               printf ("with inex = %d and flags =", inex1);
192               flags_out (flags1);
193               printf ("Got      ");
194               mpfr_dump (x2);
195               printf ("with inex = %d and flags =", inex2);
196               flags_out (flags2);
197               exit (1);
198             }
199         }
200 
201   mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
202 }
203 
204 static void
test_2exp_extreme(void)205 test_2exp_extreme (void)
206 {
207   mpfr_exp_t emin, emax;
208 
209   emin = mpfr_get_emin ();
210   emax = mpfr_get_emax ();
211 
212   set_emin (MPFR_EMIN_MIN);
213   set_emax (MPFR_EMAX_MAX);
214   test_2exp_extreme_aux ();
215 
216   set_emin (-REXP);
217   set_emax (REXP);
218   test_2exp_extreme_aux ();
219 
220   set_emin (emin);
221   set_emax (emax);
222 }
223 
224 static void
test_macros(void)225 test_macros (void)
226 {
227   mpfr_t x[3];
228   mpfr_ptr p;
229   int r;
230 
231   /* Note: the ++'s below allow one to check that the corresponding
232      arguments are evaluated only once by the macros. */
233 
234   mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
235   p = x[0];
236   r = 0;
237   mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++);
238   if (p != x[1] || r != 1)
239     {
240       printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), "
241               "r = %d (expecting 1)\n", (int) (p - x[0]), r);
242       exit (1);
243     }
244   p = x[0];
245   r = 0;
246   mpfr_set_si (p++, 0, (mpfr_rnd_t) r++);
247   if (p != x[1] || r != 1)
248     {
249       printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), "
250               "r = %d (expecting 1)\n", (int) (p - x[0]), r);
251       exit (1);
252     }
253   mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
254 }
255 
256 static void
test_macros_keyword(void)257 test_macros_keyword (void)
258 {
259   mpfr_t x;
260   unsigned long i;
261 
262   mpfr_init2 (x, 64);
263 #define MKN 0x1000000
264 #define long short
265   mpfr_set_ui (x, MKN, MPFR_RNDN);
266 #undef long
267   i = mpfr_get_ui (x, MPFR_RNDN);
268   if (i != MKN)
269     {
270       printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n",
271               (unsigned long) MKN, i);
272       exit (1);
273     }
274   mpfr_clear (x);
275 }
276 
277 static void
test_get_ui_smallneg(void)278 test_get_ui_smallneg (void)
279 {
280   mpfr_t x;
281   int i;
282 
283   mpfr_init2 (x, 64);
284 
285   for (i = 1; i <= 4; i++)
286     {
287       int r;
288 
289       mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
290       RND_LOOP (r)
291         {
292           long s;
293           unsigned long u;
294 
295           mpfr_clear_erangeflag ();
296           s = mpfr_get_si (x, r != MPFR_RNDF ? (mpfr_rnd_t) r : MPFR_RNDA);
297           if (mpfr_erangeflag_p ())
298             {
299               printf ("ERROR for get_si + ERANGE + small negative op"
300                       " for rnd = %s and x = -%d/4\n",
301                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
302               exit (1);
303             }
304           u = mpfr_get_ui (x, (mpfr_rnd_t) r);
305           if (u != 0)
306             {
307               printf ("ERROR for get_ui + ERANGE + small negative op"
308                       " for rnd = %s and x = -%d/4\n",
309                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
310               printf ("Expected 0, got %lu\n", u);
311               exit (1);
312             }
313           if ((s == 0) ^ !mpfr_erangeflag_p ())
314             {
315               const char *Not = s == 0 ? "" : " not";
316 
317               printf ("ERROR for get_ui + ERANGE + small negative op"
318                       " for rnd = %s and x = -%d/4\n",
319                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
320               printf ("The rounding integer (%ld) is%s representable in "
321                       "unsigned long,\nbut the erange flag is%s set.\n",
322                       s, Not, Not);
323               exit (1);
324             }
325         }
326     }
327 
328   mpfr_clear (x);
329 }
330 
331 /* Test mpfr_get_si and mpfr_get_ui, on values around some particular
332  * integers (see ts[] and tu[]): x = t?[i] + j/4, where '?' is 's' or
333  * 'u', and j is an integer from -8 to 8.
334  */
get_tests(void)335 static void get_tests (void)
336 {
337   mpfr_exp_t emin, emax;
338   mpfr_t x, z;
339   long ts[5] = { LONG_MIN, LONG_MAX, -17, 0, 17 };
340   unsigned long tu[3] = { 0, ULONG_MAX, 17 };
341   int s, i, j, odd, ctr = 0;
342   int inex;
343   int r;
344 
345   emin = mpfr_get_emin ();
346   emax = mpfr_get_emax ();
347 
348   /* We need the bitsize of an unsigned long + 3 bits (1 additional bit for
349    * the cases >= ULONG_MAX + 1; 2 additional bits for the fractional part).
350    */
351   mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 3);
352 
353   mpfr_init2 (z, MPFR_PREC_MIN);
354   mpfr_set_ui_2exp (z, 1, -2, MPFR_RNDN);  /* z = 1/4 */
355 
356   for (s = 1; s >= 0; s--)
357     for (i = 0; i < (s ? 5 : 3); i++)
358       {
359         odd = (s ? (unsigned long) ts[i] : tu[i]) & 1;
360         inex = s ?
361           mpfr_set_si (x, ts[i], MPFR_RNDN) :
362           mpfr_set_ui (x, tu[i], MPFR_RNDN);
363         MPFR_ASSERTN (inex == 0);
364         inex = mpfr_sub_ui (x, x, 2, MPFR_RNDN);
365         MPFR_ASSERTN (inex == 0);
366         for (j = -8; j <= 8; j++)
367           {
368             /* Test x = t?[i] + j/4 in each non-RNDF rounding mode... */
369             RND_LOOP_NO_RNDF (r)
370               {
371                 mpfr_flags_t ex_flags, flags;
372                 int e, k, overflow;
373 
374                 ctr++;  /* for the check below */
375 
376                 /* Let's determine k such that the rounded integer should
377                    be t?[i] + k, assuming an unbounded exponent range. */
378                 k = (j + 8 +
379                      (MPFR_IS_LIKE_RNDD (r, MPFR_SIGN (x)) ? 0 :
380                       MPFR_IS_LIKE_RNDU (r, MPFR_SIGN (x)) ? 3 :
381                       2)) / 4 - 2;
382                 if (r == MPFR_RNDN && ((unsigned int) j & 3) == 2 &&
383                     ((odd + k) & 1))
384                   k--;  /* even rounding */
385 
386                 /* Overflow cases. Note that with the above choices:
387                    _ t?[0] == minval(type)
388                    _ t?[1] == maxval(type)
389                 */
390                 overflow = (i == 0 && k < 0) || (i == 1 && k > 0);
391 
392                 /* Expected flags. Note that in case of overflow, only the
393                    erange flag is set. Otherwise, the result is inexact iff
394                    j mod 1 != 0, i.e. the last two bits are not 00. */
395                 ex_flags = overflow ? MPFR_FLAGS_ERANGE
396                   : ((unsigned int) j & 3) != 0 ? MPFR_FLAGS_INEXACT : 0;
397 
398                 mpfr_clear_flags ();
399 
400 #define GET_TESTS_TEST(TYPE,TZ,F,C,FMT)                                 \
401                 do {                                                    \
402                   TYPE a, d;                                            \
403                                                                         \
404                   a = TZ[i] + (overflow ? 0 : k);                       \
405                   if (e)                                                \
406                     {                                                   \
407                       mpfr_exp_t ex;                                    \
408                       ex = MPFR_GET_EXP (x);                            \
409                       set_emin (ex);                                    \
410                       set_emax (ex);                                    \
411                     }                                                   \
412                   d = F (x, (mpfr_rnd_t) r);                            \
413                   flags = __gmpfr_flags;                                \
414                   set_emin (emin);                                      \
415                   set_emax (emax);                                      \
416                   if (flags != ex_flags || a != d)                      \
417                     {                                                   \
418                       printf ("Error in get_tests for " #F " on %s%s\n", \
419                               mpfr_print_rnd_mode ((mpfr_rnd_t) r),     \
420                               e ? ", reduced exponent range" : "");     \
421                       printf ("x = t" C "[%d] + (%d/4) = ", i, j);      \
422                       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);       \
423                       printf ("\n--> k = %d\n", k);                     \
424                       printf ("Expected %l" FMT "\n", a);               \
425                       printf ("Got      %l" FMT "\n", d);               \
426                       printf ("Expected flags:");                       \
427                       flags_out (ex_flags);                             \
428                       printf ("Got flags:     ");                       \
429                       flags_out (flags);                                \
430                       exit (1);                                         \
431                     }                                                   \
432                 } while (0)
433 
434                 for (e = 0; e < 2; e++)
435                   {
436                     if (e && MPFR_IS_ZERO (x))
437                       break;
438                     if (s)
439                       GET_TESTS_TEST (long,
440                                       ts, mpfr_get_si, "s", "d");
441                     else
442                       GET_TESTS_TEST (unsigned long,
443                                       tu, mpfr_get_ui, "u", "u");
444                   }
445               }
446             inex = mpfr_add (x, x, z, MPFR_RNDN);
447             MPFR_ASSERTN (inex == 0);
448           }
449       }
450 
451   /* Check that we have tested everything: 8 = 5 + 3 integers t?[i]
452    * with 17 = 8 - (-8) + 1 additional terms (j/4) for each integer,
453    * and each non-RNDF rounding mode.
454    */
455   MPFR_ASSERTN (ctr == 8 * 17 * ((int) MPFR_RND_MAX - 1));
456 
457   mpfr_clear (x);
458   mpfr_clear (z);
459 }
460 
461 /* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
462    have all tests examine the bits in mpfr_t for what should come out.  */
463 
464 int
main(int argc,char * argv[])465 main (int argc, char *argv[])
466 {
467   mpfr_t x;
468   long k, z, d, N;
469   unsigned long zl, dl;
470   int inex;
471   int r;
472   mpfr_exp_t emin, emax;
473   int flag;
474 
475   tests_start_mpfr ();
476 
477   get_tests ();
478 
479   mpfr_init2 (x, 100);
480 
481   N = (argc == 1) ? 100000 : atol (argv[1]);
482 
483   for (k = 1; k <= N; k++)
484     {
485       z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
486       inex = mpfr_set_si (x, z, MPFR_RNDZ);
487       d = mpfr_get_si (x, MPFR_RNDZ);
488       if (d != z)
489         {
490           printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
491           exit (1);
492         }
493       if (inex)
494         {
495           printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
496                   z, inex);
497           exit (1);
498         }
499     }
500 
501   for (k = 1; k <= N; k++)
502     {
503       zl = randlimb ();
504       inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
505       dl = mpfr_get_ui (x, MPFR_RNDZ);
506       if (dl != zl)
507         {
508           printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
509           exit (1);
510         }
511       if (inex)
512         {
513           printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
514                   zl, inex);
515           exit (1);
516         }
517     }
518 
519   mpfr_set_prec (x, 2);
520   if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
521     {
522       printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
523       exit (1);
524     }
525 
526   mpfr_set_prec (x, 2);
527   if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
528     {
529       printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
530       exit (1);
531     }
532 
533   mpfr_set_prec (x, 3);
534   inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
535   if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
536     {
537       printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
538       mpfr_dump (x);
539       exit (1);
540     }
541   inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
542   if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
543     {
544       printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
545       mpfr_dump (x);
546       exit (1);
547     }
548 
549   mpfr_set_prec (x, 2);
550   inex = mpfr_set_si (x, 33096, MPFR_RNDU);
551   if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
552     {
553       printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
554               mpfr_get_si (x, MPFR_RNDZ), inex);
555       exit (1);
556     }
557   inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
558   if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
559     {
560       printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
561               mpfr_get_si (x, MPFR_RNDZ), inex);
562       exit (1);
563     }
564   /* Also test the mpfr_set_ui function (instead of macro). */
565   inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
566   if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
567     {
568       printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
569               mpfr_get_si (x, MPFR_RNDZ), inex);
570       exit (1);
571     }
572 
573   RND_LOOP (r)
574     {
575       mpfr_set_si (x, -1, (mpfr_rnd_t) r);
576       mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
577       if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
578         {
579           printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
580                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
581           exit (1);
582         }
583 
584       mpfr_set_si (x, -1, (mpfr_rnd_t) r);
585       mpfr_set_si (x, 0, (mpfr_rnd_t) r);
586       if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
587         {
588           printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
589                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
590           exit (1);
591         }
592     }
593 
594   /* check potential bug in case mp_limb_t is unsigned */
595   emax = mpfr_get_emax ();
596   set_emax (0);
597   mpfr_set_si (x, -1, MPFR_RNDN);
598   if (mpfr_sgn (x) >= 0)
599     {
600       printf ("mpfr_set_si (x, -1) fails\n");
601       exit (1);
602     }
603   set_emax (emax);
604 
605   emax = mpfr_get_emax ();
606   set_emax (5);
607   mpfr_set_prec (x, 2);
608   mpfr_set_si (x, -31, MPFR_RNDN);
609   if (mpfr_sgn (x) >= 0)
610     {
611       printf ("mpfr_set_si (x, -31) fails\n");
612       exit (1);
613     }
614   set_emax (emax);
615 
616   /* test for get_ui */
617   mpfr_set_ui (x, 0, MPFR_RNDN);
618   MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
619   mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
620   mpfr_nextabove (x);
621   mpfr_get_ui (x, MPFR_RNDU);
622 
623   /* another test for get_ui */
624   mpfr_set_prec (x, 10);
625   mpfr_set_str_binary (x, "10.101");
626   dl = mpfr_get_ui (x, MPFR_RNDN);
627   MPFR_ASSERTN (dl == 3);
628 
629   mpfr_set_str_binary (x, "-1.0");
630   mpfr_get_ui (x, MPFR_RNDN);
631 
632   mpfr_set_str_binary (x, "0.1");
633   dl = mpfr_get_ui (x, MPFR_RNDN);
634   MPFR_ASSERTN (dl == 0);
635   dl = mpfr_get_ui (x, MPFR_RNDZ);
636   MPFR_ASSERTN (dl == 0);
637   dl = mpfr_get_ui (x, MPFR_RNDD);
638   MPFR_ASSERTN (dl == 0);
639   dl = mpfr_get_ui (x, MPFR_RNDU);
640   MPFR_ASSERTN (dl == 1);
641 
642   /* coverage tests */
643   mpfr_set_prec (x, 2);
644   mpfr_set_si (x, -7, MPFR_RNDD);
645   MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
646   mpfr_set_prec (x, 2);
647   mpfr_set_ui (x, 7, MPFR_RNDU);
648   MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
649   emax = mpfr_get_emax ();
650   set_emax (3);
651   mpfr_set_ui (x, 7, MPFR_RNDU);
652   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
653   set_emax (1);
654   MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
655   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
656   set_emax (emax);
657   mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
658   MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
659   MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
660 
661   /* Test for ERANGE flag + correct behavior if overflow */
662   mpfr_set_prec (x, 256);
663   mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
664   mpfr_clear_erangeflag ();
665   dl = mpfr_get_ui (x, MPFR_RNDN);
666   if (dl != ULONG_MAX || mpfr_erangeflag_p ())
667     {
668       printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
669       exit (1);
670     }
671   mpfr_add_ui (x, x, 1, MPFR_RNDN);
672   dl = mpfr_get_ui (x, MPFR_RNDN);
673   if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
674     {
675       printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
676       exit (1);
677     }
678   mpfr_set_si (x, -1, MPFR_RNDN);
679   mpfr_clear_erangeflag ();
680   dl = mpfr_get_ui (x, MPFR_RNDN);
681   if (dl != 0 || !mpfr_erangeflag_p ())
682     {
683       printf ("ERROR for get_ui + ERANGE + -1 \n");
684       exit (1);
685     }
686   mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
687   mpfr_clear_erangeflag ();
688   d = mpfr_get_si (x, MPFR_RNDN);
689   if (d != LONG_MAX || mpfr_erangeflag_p ())
690     {
691       printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
692       exit (1);
693     }
694   mpfr_add_ui (x, x, 1, MPFR_RNDN);
695   d = mpfr_get_si (x, MPFR_RNDN);
696   if (d != LONG_MAX || !mpfr_erangeflag_p ())
697     {
698       printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
699       exit (1);
700     }
701   mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
702   mpfr_clear_erangeflag ();
703   d = mpfr_get_si (x, MPFR_RNDN);
704   if (d != LONG_MIN || mpfr_erangeflag_p ())
705     {
706       printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
707       exit (1);
708     }
709   mpfr_sub_ui (x, x, 1, MPFR_RNDN);
710   d = mpfr_get_si (x, MPFR_RNDN);
711   if (d != LONG_MIN || !mpfr_erangeflag_p ())
712     {
713       printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
714       exit (1);
715     }
716 
717   mpfr_set_nan (x);
718   mpfr_clear_flags ();
719   d = mpfr_get_ui (x, MPFR_RNDN);
720   if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
721     {
722       printf ("ERROR for get_ui + NaN\n");
723       exit (1);
724     }
725   mpfr_clear_erangeflag ();
726   d = mpfr_get_si (x, MPFR_RNDN);
727   if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
728     {
729       printf ("ERROR for get_si + NaN\n");
730       exit (1);
731     }
732 
733   emin = mpfr_get_emin ();
734   mpfr_set_prec (x, 2);
735 
736   set_emin (4);
737   mpfr_clear_flags ();
738   mpfr_set_ui (x, 7, MPFR_RNDU);
739   flag = mpfr_underflow_p ();
740   set_emin (emin);
741   if (mpfr_cmp_ui (x, 8) != 0)
742     {
743       printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
744       exit (1);
745     }
746   if (flag)
747     {
748       printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
749               "with prec = 2, emin = 4\n");
750       exit (1);
751     }
752 
753   set_emin (4);
754   mpfr_clear_flags ();
755   mpfr_set_si (x, -7, MPFR_RNDD);
756   flag = mpfr_underflow_p ();
757   set_emin (emin);
758   if (mpfr_cmp_si (x, -8) != 0)
759     {
760       printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
761       exit (1);
762     }
763   if (flag)
764     {
765       printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
766               "with prec = 2, emin = 4\n");
767       exit (1);
768     }
769 
770   mpfr_clear (x);
771 
772   test_2exp ();
773   test_2exp_extreme ();
774   test_macros ();
775   test_macros_keyword ();
776   test_get_ui_smallneg ();
777   tests_end_mpfr ();
778   return 0;
779 }
780