(root)/
mpfr-4.2.1/
tests/
tset_si.c
       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
      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
      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
     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
     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
     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
     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   */
     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
     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  }