Home | History | Annotate | Line # | Download | only in tests
tset_si.c revision 1.1.1.3.2.1
      1  1.1.1.3.2.1  pgoyette /* Test file for mpfr_set_si, mpfr_set_ui, mpfr_get_si and mpfr_get_ui.
      2          1.1       mrg 
      3  1.1.1.3.2.1  pgoyette Copyright 1999, 2001-2018 Free Software Foundation, Inc.
      4      1.1.1.3       mrg Contributed by the AriC and Caramba projects, INRIA.
      5          1.1       mrg 
      6          1.1       mrg This file is part of the GNU MPFR Library.
      7          1.1       mrg 
      8          1.1       mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9          1.1       mrg it under the terms of the GNU Lesser General Public License as published by
     10          1.1       mrg the Free Software Foundation; either version 3 of the License, or (at your
     11          1.1       mrg option) any later version.
     12          1.1       mrg 
     13          1.1       mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14          1.1       mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15          1.1       mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16          1.1       mrg License for more details.
     17          1.1       mrg 
     18          1.1       mrg You should have received a copy of the GNU Lesser General Public License
     19          1.1       mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20          1.1       mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21          1.1       mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22          1.1       mrg 
     23          1.1       mrg #include "mpfr-test.h"
     24          1.1       mrg 
     25  1.1.1.3.2.1  pgoyette #define PRINT_ERROR(str) \
     26  1.1.1.3.2.1  pgoyette   do { printf ("Error for %s\n", str); exit (1); } while (0)
     27          1.1       mrg 
     28          1.1       mrg static void
     29          1.1       mrg test_2exp (void)
     30          1.1       mrg {
     31          1.1       mrg   mpfr_t x;
     32          1.1       mrg   int res;
     33          1.1       mrg 
     34          1.1       mrg   mpfr_init2 (x, 32);
     35          1.1       mrg 
     36          1.1       mrg   mpfr_set_ui_2exp (x, 1, 0, MPFR_RNDN);
     37  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_ui (x, 1) != 0)
     38  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(1U,0)");
     39          1.1       mrg 
     40          1.1       mrg   mpfr_set_ui_2exp (x, 1024, -10, MPFR_RNDN);
     41  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_ui(x, 1) != 0)
     42  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(1024U,-10)");
     43          1.1       mrg 
     44          1.1       mrg   mpfr_set_ui_2exp (x, 1024, 10, MPFR_RNDN);
     45  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_ui (x, 1024 * 1024) != 0)
     46  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(1024U,+10)");
     47          1.1       mrg 
     48          1.1       mrg   mpfr_set_si_2exp (x, -1024L * 1024L, -10, MPFR_RNDN);
     49  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_si (x, -1024) != 0)
     50  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(1M,-10)");
     51          1.1       mrg 
     52          1.1       mrg   mpfr_set_ui_2exp (x, 0x92345678, 16, MPFR_RNDN);
     53  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_str (x, "92345678@4", 16, MPFR_RNDN) != 0)
     54  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(x92345678U,+16)");
     55          1.1       mrg 
     56          1.1       mrg   mpfr_set_si_2exp (x, -0x1ABCDEF0, -256, MPFR_RNDN);
     57  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_str (x, "-1ABCDEF0@-64", 16, MPFR_RNDN) != 0)
     58  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("(-x1ABCDEF0,-256)");
     59          1.1       mrg 
     60          1.1       mrg   mpfr_set_prec (x, 2);
     61          1.1       mrg   res = mpfr_set_si_2exp (x, 7, 10, MPFR_RNDU);
     62  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
     63  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("Prec 2 + si_2exp");
     64          1.1       mrg 
     65          1.1       mrg   res = mpfr_set_ui_2exp (x, 7, 10, MPFR_RNDU);
     66  1.1.1.3.2.1  pgoyette   if (mpfr_cmp_ui (x, 1<<13) != 0 || res <= 0)
     67  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("Prec 2 + ui_2exp");
     68          1.1       mrg 
     69          1.1       mrg   mpfr_clear_flags ();
     70          1.1       mrg   mpfr_set_ui_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
     71          1.1       mrg   if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
     72  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_ui_2exp and overflow (bad result)");
     73          1.1       mrg   if (!mpfr_overflow_p ())
     74  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_ui_2exp and overflow (overflow flag not set)");
     75          1.1       mrg 
     76          1.1       mrg   mpfr_clear_flags ();
     77          1.1       mrg   mpfr_set_si_2exp (x, 17, MPFR_EMAX_MAX, MPFR_RNDN);
     78          1.1       mrg   if (!mpfr_inf_p (x) || MPFR_IS_NEG (x))
     79  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (bad result)");
     80          1.1       mrg   if (!mpfr_overflow_p ())
     81  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_si_2exp (pos) and overflow (overflow flag not set)");
     82          1.1       mrg 
     83          1.1       mrg   mpfr_clear_flags ();
     84          1.1       mrg   mpfr_set_si_2exp (x, -17, MPFR_EMAX_MAX, MPFR_RNDN);
     85          1.1       mrg   if (!mpfr_inf_p (x) || MPFR_IS_POS (x))
     86  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (bad result)");
     87          1.1       mrg   if (!mpfr_overflow_p ())
     88  1.1.1.3.2.1  pgoyette     PRINT_ERROR ("mpfr_set_si_2exp (neg) and overflow (overflow flag not set)");
     89          1.1       mrg 
     90          1.1       mrg   mpfr_clear (x);
     91          1.1       mrg }
     92          1.1       mrg 
     93          1.1       mrg static void
     94          1.1       mrg test_macros (void)
     95          1.1       mrg {
     96          1.1       mrg   mpfr_t x[3];
     97          1.1       mrg   mpfr_ptr p;
     98          1.1       mrg   int r;
     99          1.1       mrg 
    100  1.1.1.3.2.1  pgoyette   /* Note: the ++'s below allow one to check that the corresponding
    101  1.1.1.3.2.1  pgoyette      arguments are evaluated only once by the macros. */
    102  1.1.1.3.2.1  pgoyette 
    103          1.1       mrg   mpfr_inits (x[0], x[1], x[2], (mpfr_ptr) 0);
    104          1.1       mrg   p = x[0];
    105          1.1       mrg   r = 0;
    106          1.1       mrg   mpfr_set_ui (p++, 0, (mpfr_rnd_t) r++);
    107          1.1       mrg   if (p != x[1] || r != 1)
    108          1.1       mrg     {
    109          1.1       mrg       printf ("Error in mpfr_set_ui macro: p - x[0] = %d (expecting 1), "
    110          1.1       mrg               "r = %d (expecting 1)\n", (int) (p - x[0]), r);
    111          1.1       mrg       exit (1);
    112          1.1       mrg     }
    113          1.1       mrg   p = x[0];
    114          1.1       mrg   r = 0;
    115          1.1       mrg   mpfr_set_si (p++, 0, (mpfr_rnd_t) r++);
    116          1.1       mrg   if (p != x[1] || r != 1)
    117          1.1       mrg     {
    118          1.1       mrg       printf ("Error in mpfr_set_si macro: p - x[0] = %d (expecting 1), "
    119          1.1       mrg               "r = %d (expecting 1)\n", (int) (p - x[0]), r);
    120          1.1       mrg       exit (1);
    121          1.1       mrg     }
    122          1.1       mrg   mpfr_clears (x[0], x[1], x[2], (mpfr_ptr) 0);
    123          1.1       mrg }
    124          1.1       mrg 
    125      1.1.1.2       mrg static void
    126      1.1.1.2       mrg test_macros_keyword (void)
    127      1.1.1.2       mrg {
    128      1.1.1.2       mrg   mpfr_t x;
    129      1.1.1.2       mrg   unsigned long i;
    130      1.1.1.2       mrg 
    131      1.1.1.2       mrg   mpfr_init2 (x, 64);
    132      1.1.1.2       mrg #define MKN 0x1000000
    133      1.1.1.2       mrg #define long short
    134      1.1.1.2       mrg   mpfr_set_ui (x, MKN, MPFR_RNDN);
    135      1.1.1.2       mrg #undef long
    136      1.1.1.2       mrg   i = mpfr_get_ui (x, MPFR_RNDN);
    137      1.1.1.2       mrg   if (i != MKN)
    138      1.1.1.2       mrg     {
    139      1.1.1.2       mrg       printf ("Error in test_macros_keyword: expected 0x%lx, got 0x%lx.\n",
    140      1.1.1.2       mrg               (unsigned long) MKN, i);
    141      1.1.1.2       mrg       exit (1);
    142      1.1.1.2       mrg     }
    143      1.1.1.2       mrg   mpfr_clear (x);
    144      1.1.1.2       mrg }
    145      1.1.1.2       mrg 
    146  1.1.1.3.2.1  pgoyette static void
    147  1.1.1.3.2.1  pgoyette test_get_ui_smallneg (void)
    148  1.1.1.3.2.1  pgoyette {
    149  1.1.1.3.2.1  pgoyette   mpfr_t x;
    150  1.1.1.3.2.1  pgoyette   int i;
    151  1.1.1.3.2.1  pgoyette 
    152  1.1.1.3.2.1  pgoyette   mpfr_init2 (x, 64);
    153  1.1.1.3.2.1  pgoyette 
    154  1.1.1.3.2.1  pgoyette   for (i = 1; i <= 4; i++)
    155  1.1.1.3.2.1  pgoyette     {
    156  1.1.1.3.2.1  pgoyette       int r;
    157  1.1.1.3.2.1  pgoyette 
    158  1.1.1.3.2.1  pgoyette       mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
    159  1.1.1.3.2.1  pgoyette       RND_LOOP (r)
    160  1.1.1.3.2.1  pgoyette         {
    161  1.1.1.3.2.1  pgoyette           long s;
    162  1.1.1.3.2.1  pgoyette           unsigned long u;
    163  1.1.1.3.2.1  pgoyette 
    164  1.1.1.3.2.1  pgoyette           mpfr_clear_erangeflag ();
    165  1.1.1.3.2.1  pgoyette           s = mpfr_get_si (x, r != MPFR_RNDF ? (mpfr_rnd_t) r : MPFR_RNDA);
    166  1.1.1.3.2.1  pgoyette           if (mpfr_erangeflag_p ())
    167  1.1.1.3.2.1  pgoyette             {
    168  1.1.1.3.2.1  pgoyette               printf ("ERROR for get_si + ERANGE + small negative op"
    169  1.1.1.3.2.1  pgoyette                       " for rnd = %s and x = -%d/4\n",
    170  1.1.1.3.2.1  pgoyette                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    171  1.1.1.3.2.1  pgoyette               exit (1);
    172  1.1.1.3.2.1  pgoyette             }
    173  1.1.1.3.2.1  pgoyette           u = mpfr_get_ui (x, (mpfr_rnd_t) r);
    174  1.1.1.3.2.1  pgoyette           if (u != 0)
    175  1.1.1.3.2.1  pgoyette             {
    176  1.1.1.3.2.1  pgoyette               printf ("ERROR for get_ui + ERANGE + small negative op"
    177  1.1.1.3.2.1  pgoyette                       " for rnd = %s and x = -%d/4\n",
    178  1.1.1.3.2.1  pgoyette                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    179  1.1.1.3.2.1  pgoyette               printf ("Expected 0, got %lu\n", u);
    180  1.1.1.3.2.1  pgoyette               exit (1);
    181  1.1.1.3.2.1  pgoyette             }
    182  1.1.1.3.2.1  pgoyette           if ((s == 0) ^ !mpfr_erangeflag_p ())
    183  1.1.1.3.2.1  pgoyette             {
    184  1.1.1.3.2.1  pgoyette               const char *Not = s == 0 ? "" : " not";
    185  1.1.1.3.2.1  pgoyette 
    186  1.1.1.3.2.1  pgoyette               printf ("ERROR for get_ui + ERANGE + small negative op"
    187  1.1.1.3.2.1  pgoyette                       " for rnd = %s and x = -%d/4\n",
    188  1.1.1.3.2.1  pgoyette                       mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
    189  1.1.1.3.2.1  pgoyette               printf ("The rounding integer (%ld) is%s representable in "
    190  1.1.1.3.2.1  pgoyette                       "unsigned long,\nbut the erange flag is%s set.\n",
    191  1.1.1.3.2.1  pgoyette                       s, Not, Not);
    192  1.1.1.3.2.1  pgoyette               exit (1);
    193  1.1.1.3.2.1  pgoyette             }
    194  1.1.1.3.2.1  pgoyette         }
    195  1.1.1.3.2.1  pgoyette     }
    196  1.1.1.3.2.1  pgoyette 
    197  1.1.1.3.2.1  pgoyette   mpfr_clear (x);
    198  1.1.1.3.2.1  pgoyette }
    199  1.1.1.3.2.1  pgoyette 
    200  1.1.1.3.2.1  pgoyette /* Test mpfr_get_si and mpfr_get_ui, on values around some particular
    201  1.1.1.3.2.1  pgoyette  * integers (see ts[] and tu[]): x = t?[i] + j/4, where '?' is 's' or
    202  1.1.1.3.2.1  pgoyette  * 'u', and j is an integer from -8 to 8.
    203  1.1.1.3.2.1  pgoyette  */
    204  1.1.1.3.2.1  pgoyette static void get_tests (void)
    205  1.1.1.3.2.1  pgoyette {
    206  1.1.1.3.2.1  pgoyette   mpfr_exp_t emin, emax;
    207  1.1.1.3.2.1  pgoyette   mpfr_t x, z;
    208  1.1.1.3.2.1  pgoyette   long ts[5] = { LONG_MIN, LONG_MAX, -17, 0, 17 };
    209  1.1.1.3.2.1  pgoyette   unsigned long tu[3] = { 0, ULONG_MAX, 17 };
    210  1.1.1.3.2.1  pgoyette   int s, i, j, odd, ctr = 0;
    211  1.1.1.3.2.1  pgoyette   int inex;
    212  1.1.1.3.2.1  pgoyette   int r;
    213  1.1.1.3.2.1  pgoyette 
    214  1.1.1.3.2.1  pgoyette   emin = mpfr_get_emin ();
    215  1.1.1.3.2.1  pgoyette   emax = mpfr_get_emax ();
    216  1.1.1.3.2.1  pgoyette 
    217  1.1.1.3.2.1  pgoyette   /* We need the bitsize of an unsigned long + 3 bits (1 additional bit for
    218  1.1.1.3.2.1  pgoyette    * the cases >= ULONG_MAX + 1; 2 additional bits for the fractional part).
    219  1.1.1.3.2.1  pgoyette    */
    220  1.1.1.3.2.1  pgoyette   mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 3);
    221  1.1.1.3.2.1  pgoyette 
    222  1.1.1.3.2.1  pgoyette   mpfr_init2 (z, MPFR_PREC_MIN);
    223  1.1.1.3.2.1  pgoyette   mpfr_set_ui_2exp (z, 1, -2, MPFR_RNDN);  /* z = 1/4 */
    224  1.1.1.3.2.1  pgoyette 
    225  1.1.1.3.2.1  pgoyette   for (s = 1; s >= 0; s--)
    226  1.1.1.3.2.1  pgoyette     for (i = 0; i < (s ? 5 : 3); i++)
    227  1.1.1.3.2.1  pgoyette       {
    228  1.1.1.3.2.1  pgoyette         odd = (s ? (unsigned long) ts[i] : tu[i]) & 1;
    229  1.1.1.3.2.1  pgoyette         inex = s ?
    230  1.1.1.3.2.1  pgoyette           mpfr_set_si (x, ts[i], MPFR_RNDN) :
    231  1.1.1.3.2.1  pgoyette           mpfr_set_ui (x, tu[i], MPFR_RNDN);
    232  1.1.1.3.2.1  pgoyette         MPFR_ASSERTN (inex == 0);
    233  1.1.1.3.2.1  pgoyette         inex = mpfr_sub_ui (x, x, 2, MPFR_RNDN);
    234  1.1.1.3.2.1  pgoyette         MPFR_ASSERTN (inex == 0);
    235  1.1.1.3.2.1  pgoyette         for (j = -8; j <= 8; j++)
    236  1.1.1.3.2.1  pgoyette           {
    237  1.1.1.3.2.1  pgoyette             /* Test x = t?[i] + j/4 in each non-RNDF rounding mode... */
    238  1.1.1.3.2.1  pgoyette             RND_LOOP_NO_RNDF (r)
    239  1.1.1.3.2.1  pgoyette               {
    240  1.1.1.3.2.1  pgoyette                 mpfr_flags_t ex_flags, flags;
    241  1.1.1.3.2.1  pgoyette                 int e, k, overflow;
    242  1.1.1.3.2.1  pgoyette 
    243  1.1.1.3.2.1  pgoyette                 ctr++;  /* for the check below */
    244  1.1.1.3.2.1  pgoyette 
    245  1.1.1.3.2.1  pgoyette                 /* Let's determine k such that the rounded integer should
    246  1.1.1.3.2.1  pgoyette                    be t?[i] + k, assuming an unbounded exponent range. */
    247  1.1.1.3.2.1  pgoyette                 k = (j + 8 +
    248  1.1.1.3.2.1  pgoyette                      (MPFR_IS_LIKE_RNDD (r, MPFR_SIGN (x)) ? 0 :
    249  1.1.1.3.2.1  pgoyette                       MPFR_IS_LIKE_RNDU (r, MPFR_SIGN (x)) ? 3 :
    250  1.1.1.3.2.1  pgoyette                       2)) / 4 - 2;
    251  1.1.1.3.2.1  pgoyette                 if (r == MPFR_RNDN && ((unsigned int) j & 3) == 2 &&
    252  1.1.1.3.2.1  pgoyette                     ((odd + k) & 1))
    253  1.1.1.3.2.1  pgoyette                   k--;  /* even rounding */
    254  1.1.1.3.2.1  pgoyette 
    255  1.1.1.3.2.1  pgoyette                 /* Overflow cases. Note that with the above choices:
    256  1.1.1.3.2.1  pgoyette                    _ t?[0] == minval(type)
    257  1.1.1.3.2.1  pgoyette                    _ t?[1] == maxval(type)
    258  1.1.1.3.2.1  pgoyette                 */
    259  1.1.1.3.2.1  pgoyette                 overflow = (i == 0 && k < 0) || (i == 1 && k > 0);
    260  1.1.1.3.2.1  pgoyette 
    261  1.1.1.3.2.1  pgoyette                 /* Expected flags. Note that in case of overflow, only the
    262  1.1.1.3.2.1  pgoyette                    erange flag is set. Otherwise, the result is inexact iff
    263  1.1.1.3.2.1  pgoyette                    j mod 1 != 0, i.e. the last two bits are not 00. */
    264  1.1.1.3.2.1  pgoyette                 ex_flags = overflow ? MPFR_FLAGS_ERANGE
    265  1.1.1.3.2.1  pgoyette                   : ((unsigned int) j & 3) != 0 ? MPFR_FLAGS_INEXACT : 0;
    266  1.1.1.3.2.1  pgoyette 
    267  1.1.1.3.2.1  pgoyette                 mpfr_clear_flags ();
    268  1.1.1.3.2.1  pgoyette 
    269  1.1.1.3.2.1  pgoyette #define GET_TESTS_TEST(TYPE,TZ,F,C,FMT)                                 \
    270  1.1.1.3.2.1  pgoyette                 do {                                                    \
    271  1.1.1.3.2.1  pgoyette                   TYPE a, d;                                            \
    272  1.1.1.3.2.1  pgoyette                                                                         \
    273  1.1.1.3.2.1  pgoyette                   a = TZ[i] + (overflow ? 0 : k);                       \
    274  1.1.1.3.2.1  pgoyette                   if (e)                                                \
    275  1.1.1.3.2.1  pgoyette                     {                                                   \
    276  1.1.1.3.2.1  pgoyette                       mpfr_exp_t ex;                                    \
    277  1.1.1.3.2.1  pgoyette                       ex = MPFR_GET_EXP (x);                            \
    278  1.1.1.3.2.1  pgoyette                       set_emin (ex);                                    \
    279  1.1.1.3.2.1  pgoyette                       set_emax (ex);                                    \
    280  1.1.1.3.2.1  pgoyette                     }                                                   \
    281  1.1.1.3.2.1  pgoyette                   d = F (x, (mpfr_rnd_t) r);                            \
    282  1.1.1.3.2.1  pgoyette                   flags = __gmpfr_flags;                                \
    283  1.1.1.3.2.1  pgoyette                   set_emin (emin);                                      \
    284  1.1.1.3.2.1  pgoyette                   set_emax (emax);                                      \
    285  1.1.1.3.2.1  pgoyette                   if (flags != ex_flags || a != d)                      \
    286  1.1.1.3.2.1  pgoyette                     {                                                   \
    287  1.1.1.3.2.1  pgoyette                       printf ("Error in get_tests for " #F " on %s%s\n", \
    288  1.1.1.3.2.1  pgoyette                               mpfr_print_rnd_mode ((mpfr_rnd_t) r),     \
    289  1.1.1.3.2.1  pgoyette                               e ? ", reduced exponent range" : "");     \
    290  1.1.1.3.2.1  pgoyette                       printf ("x = t" C "[%d] + (%d/4) = ", i, j);      \
    291  1.1.1.3.2.1  pgoyette                       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);       \
    292  1.1.1.3.2.1  pgoyette                       printf ("\n--> k = %d\n", k);                     \
    293  1.1.1.3.2.1  pgoyette                       printf ("Expected %l" FMT "\n", a);               \
    294  1.1.1.3.2.1  pgoyette                       printf ("Got      %l" FMT "\n", d);               \
    295  1.1.1.3.2.1  pgoyette                       printf ("Expected flags:");                       \
    296  1.1.1.3.2.1  pgoyette                       flags_out (ex_flags);                             \
    297  1.1.1.3.2.1  pgoyette                       printf ("Got flags:     ");                       \
    298  1.1.1.3.2.1  pgoyette                       flags_out (flags);                                \
    299  1.1.1.3.2.1  pgoyette                       exit (1);                                         \
    300  1.1.1.3.2.1  pgoyette                     }                                                   \
    301  1.1.1.3.2.1  pgoyette                 } while (0)
    302  1.1.1.3.2.1  pgoyette 
    303  1.1.1.3.2.1  pgoyette                 for (e = 0; e < 2; e++)
    304  1.1.1.3.2.1  pgoyette                   {
    305  1.1.1.3.2.1  pgoyette                     if (e && MPFR_IS_ZERO (x))
    306  1.1.1.3.2.1  pgoyette                       break;
    307  1.1.1.3.2.1  pgoyette                     if (s)
    308  1.1.1.3.2.1  pgoyette                       GET_TESTS_TEST (long,
    309  1.1.1.3.2.1  pgoyette                                       ts, mpfr_get_si, "s", "d");
    310  1.1.1.3.2.1  pgoyette                     else
    311  1.1.1.3.2.1  pgoyette                       GET_TESTS_TEST (unsigned long,
    312  1.1.1.3.2.1  pgoyette                                       tu, mpfr_get_ui, "u", "u");
    313  1.1.1.3.2.1  pgoyette                   }
    314  1.1.1.3.2.1  pgoyette               }
    315  1.1.1.3.2.1  pgoyette             inex = mpfr_add (x, x, z, MPFR_RNDN);
    316  1.1.1.3.2.1  pgoyette             MPFR_ASSERTN (inex == 0);
    317  1.1.1.3.2.1  pgoyette           }
    318  1.1.1.3.2.1  pgoyette       }
    319  1.1.1.3.2.1  pgoyette 
    320  1.1.1.3.2.1  pgoyette   /* Check that we have tested everything: 8 = 5 + 3 integers t?[i]
    321  1.1.1.3.2.1  pgoyette    * with 17 = 8 - (-8) + 1 additional terms (j/4) for each integer,
    322  1.1.1.3.2.1  pgoyette    * and each non-RNDF rounding mode.
    323  1.1.1.3.2.1  pgoyette    */
    324  1.1.1.3.2.1  pgoyette   MPFR_ASSERTN (ctr == 8 * 17 * ((int) MPFR_RND_MAX - 1));
    325  1.1.1.3.2.1  pgoyette 
    326  1.1.1.3.2.1  pgoyette   mpfr_clear (x);
    327  1.1.1.3.2.1  pgoyette   mpfr_clear (z);
    328  1.1.1.3.2.1  pgoyette }
    329  1.1.1.3.2.1  pgoyette 
    330          1.1       mrg /* FIXME: Comparing against mpfr_get_si/ui is not ideal, it'd be better to
    331          1.1       mrg    have all tests examine the bits in mpfr_t for what should come out.  */
    332          1.1       mrg 
    333          1.1       mrg int
    334          1.1       mrg main (int argc, char *argv[])
    335          1.1       mrg {
    336          1.1       mrg   mpfr_t x;
    337          1.1       mrg   long k, z, d, N;
    338          1.1       mrg   unsigned long zl, dl;
    339          1.1       mrg   int inex;
    340          1.1       mrg   int r;
    341          1.1       mrg   mpfr_exp_t emin, emax;
    342          1.1       mrg   int flag;
    343          1.1       mrg 
    344          1.1       mrg   tests_start_mpfr ();
    345          1.1       mrg 
    346  1.1.1.3.2.1  pgoyette   get_tests ();
    347  1.1.1.3.2.1  pgoyette 
    348          1.1       mrg   mpfr_init2 (x, 100);
    349          1.1       mrg 
    350  1.1.1.3.2.1  pgoyette   N = (argc == 1) ? 100000 : atol (argv[1]);
    351          1.1       mrg 
    352          1.1       mrg   for (k = 1; k <= N; k++)
    353          1.1       mrg     {
    354          1.1       mrg       z = (long) (randlimb () & LONG_MAX) + LONG_MIN / 2;
    355          1.1       mrg       inex = mpfr_set_si (x, z, MPFR_RNDZ);
    356          1.1       mrg       d = mpfr_get_si (x, MPFR_RNDZ);
    357          1.1       mrg       if (d != z)
    358          1.1       mrg         {
    359          1.1       mrg           printf ("Error in mpfr_set_si: expected %ld got %ld\n", z, d);
    360          1.1       mrg           exit (1);
    361          1.1       mrg         }
    362          1.1       mrg       if (inex)
    363          1.1       mrg         {
    364          1.1       mrg           printf ("Error in mpfr_set_si: inex value incorrect for %ld: %d\n",
    365          1.1       mrg                   z, inex);
    366          1.1       mrg           exit (1);
    367          1.1       mrg         }
    368          1.1       mrg     }
    369          1.1       mrg 
    370          1.1       mrg   for (k = 1; k <= N; k++)
    371          1.1       mrg     {
    372          1.1       mrg       zl = randlimb ();
    373          1.1       mrg       inex = mpfr_set_ui (x, zl, MPFR_RNDZ);
    374          1.1       mrg       dl = mpfr_get_ui (x, MPFR_RNDZ);
    375          1.1       mrg       if (dl != zl)
    376          1.1       mrg         {
    377          1.1       mrg           printf ("Error in mpfr_set_ui: expected %lu got %lu\n", zl, dl);
    378          1.1       mrg           exit (1);
    379          1.1       mrg         }
    380          1.1       mrg       if (inex)
    381          1.1       mrg         {
    382          1.1       mrg           printf ("Error in mpfr_set_ui: inex value incorrect for %lu: %d\n",
    383          1.1       mrg                   zl, inex);
    384          1.1       mrg           exit (1);
    385          1.1       mrg         }
    386          1.1       mrg     }
    387          1.1       mrg 
    388          1.1       mrg   mpfr_set_prec (x, 2);
    389          1.1       mrg   if (mpfr_set_si (x, 5, MPFR_RNDZ) >= 0)
    390          1.1       mrg     {
    391          1.1       mrg       printf ("Wrong inexact flag for x=5, rnd=MPFR_RNDZ\n");
    392          1.1       mrg       exit (1);
    393          1.1       mrg     }
    394          1.1       mrg 
    395          1.1       mrg   mpfr_set_prec (x, 2);
    396          1.1       mrg   if (mpfr_set_si (x, -5, MPFR_RNDZ) <= 0)
    397          1.1       mrg     {
    398          1.1       mrg       printf ("Wrong inexact flag for x=-5, rnd=MPFR_RNDZ\n");
    399          1.1       mrg       exit (1);
    400          1.1       mrg     }
    401          1.1       mrg 
    402          1.1       mrg   mpfr_set_prec (x, 3);
    403          1.1       mrg   inex = mpfr_set_si (x, 77617, MPFR_RNDD); /* should be 65536 */
    404  1.1.1.3.2.1  pgoyette   if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
    405          1.1       mrg     {
    406          1.1       mrg       printf ("Error in mpfr_set_si(x:3, 77617, MPFR_RNDD)\n");
    407  1.1.1.3.2.1  pgoyette       mpfr_dump (x);
    408          1.1       mrg       exit (1);
    409          1.1       mrg     }
    410          1.1       mrg   inex = mpfr_set_ui (x, 77617, MPFR_RNDD); /* should be 65536 */
    411  1.1.1.3.2.1  pgoyette   if (MPFR_MANT(x)[0] != MPFR_LIMB_HIGHBIT || inex >= 0)
    412          1.1       mrg     {
    413          1.1       mrg       printf ("Error in mpfr_set_ui(x:3, 77617, MPFR_RNDD)\n");
    414  1.1.1.3.2.1  pgoyette       mpfr_dump (x);
    415          1.1       mrg       exit (1);
    416          1.1       mrg     }
    417          1.1       mrg 
    418          1.1       mrg   mpfr_set_prec (x, 2);
    419          1.1       mrg   inex = mpfr_set_si (x, 33096, MPFR_RNDU);
    420          1.1       mrg   if (mpfr_get_si (x, MPFR_RNDZ) != 49152 || inex <= 0)
    421          1.1       mrg     {
    422          1.1       mrg       printf ("Error in mpfr_set_si, exp. 49152, got %ld, inex %d\n",
    423          1.1       mrg               mpfr_get_si (x, MPFR_RNDZ), inex);
    424          1.1       mrg       exit (1);
    425          1.1       mrg     }
    426          1.1       mrg   inex = mpfr_set_ui (x, 33096, MPFR_RNDU);
    427          1.1       mrg   if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    428          1.1       mrg     {
    429          1.1       mrg       printf ("Error in mpfr_set_ui, exp. 49152, got %ld, inex %d\n",
    430          1.1       mrg               mpfr_get_si (x, MPFR_RNDZ), inex);
    431          1.1       mrg       exit (1);
    432          1.1       mrg     }
    433      1.1.1.2       mrg   /* Also test the mpfr_set_ui function (instead of macro). */
    434      1.1.1.2       mrg   inex = (mpfr_set_ui) (x, 33096, MPFR_RNDU);
    435      1.1.1.2       mrg   if (mpfr_get_si (x, MPFR_RNDZ) != 49152)
    436      1.1.1.2       mrg     {
    437      1.1.1.2       mrg       printf ("Error in mpfr_set_ui function, exp. 49152, got %ld, inex %d\n",
    438      1.1.1.2       mrg               mpfr_get_si (x, MPFR_RNDZ), inex);
    439      1.1.1.2       mrg       exit (1);
    440      1.1.1.2       mrg     }
    441          1.1       mrg 
    442          1.1       mrg   for (r = 0 ; r < MPFR_RND_MAX ; r++)
    443          1.1       mrg     {
    444          1.1       mrg       mpfr_set_si (x, -1, (mpfr_rnd_t) r);
    445          1.1       mrg       mpfr_set_ui (x, 0, (mpfr_rnd_t) r);
    446          1.1       mrg       if (MPFR_IS_NEG (x) || mpfr_get_ui (x, (mpfr_rnd_t) r) != 0)
    447          1.1       mrg         {
    448          1.1       mrg           printf ("mpfr_set_ui (x, 0) gives -0 for %s\n",
    449          1.1       mrg                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    450          1.1       mrg           exit (1);
    451          1.1       mrg         }
    452          1.1       mrg 
    453          1.1       mrg       mpfr_set_si (x, -1, (mpfr_rnd_t) r);
    454          1.1       mrg       mpfr_set_si (x, 0, (mpfr_rnd_t) r);
    455          1.1       mrg       if (MPFR_IS_NEG (x) || mpfr_get_si (x, (mpfr_rnd_t) r) != 0)
    456          1.1       mrg         {
    457          1.1       mrg           printf ("mpfr_set_si (x, 0) gives -0 for %s\n",
    458          1.1       mrg                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
    459          1.1       mrg           exit (1);
    460          1.1       mrg         }
    461          1.1       mrg     }
    462          1.1       mrg 
    463          1.1       mrg   /* check potential bug in case mp_limb_t is unsigned */
    464          1.1       mrg   emax = mpfr_get_emax ();
    465          1.1       mrg   set_emax (0);
    466          1.1       mrg   mpfr_set_si (x, -1, MPFR_RNDN);
    467          1.1       mrg   if (mpfr_sgn (x) >= 0)
    468          1.1       mrg     {
    469          1.1       mrg       printf ("mpfr_set_si (x, -1) fails\n");
    470          1.1       mrg       exit (1);
    471          1.1       mrg     }
    472          1.1       mrg   set_emax (emax);
    473          1.1       mrg 
    474          1.1       mrg   emax = mpfr_get_emax ();
    475          1.1       mrg   set_emax (5);
    476          1.1       mrg   mpfr_set_prec (x, 2);
    477          1.1       mrg   mpfr_set_si (x, -31, MPFR_RNDN);
    478          1.1       mrg   if (mpfr_sgn (x) >= 0)
    479          1.1       mrg     {
    480          1.1       mrg       printf ("mpfr_set_si (x, -31) fails\n");
    481          1.1       mrg       exit (1);
    482          1.1       mrg     }
    483          1.1       mrg   set_emax (emax);
    484          1.1       mrg 
    485          1.1       mrg   /* test for get_ui */
    486          1.1       mrg   mpfr_set_ui (x, 0, MPFR_RNDN);
    487          1.1       mrg   MPFR_ASSERTN(mpfr_get_ui (x, MPFR_RNDN) == 0);
    488          1.1       mrg   mpfr_set_ui (x, ULONG_MAX, MPFR_RNDU);
    489          1.1       mrg   mpfr_nextabove (x);
    490          1.1       mrg   mpfr_get_ui (x, MPFR_RNDU);
    491          1.1       mrg 
    492          1.1       mrg   /* another test for get_ui */
    493          1.1       mrg   mpfr_set_prec (x, 10);
    494          1.1       mrg   mpfr_set_str_binary (x, "10.101");
    495          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDN);
    496          1.1       mrg   MPFR_ASSERTN (dl == 3);
    497          1.1       mrg 
    498          1.1       mrg   mpfr_set_str_binary (x, "-1.0");
    499          1.1       mrg   mpfr_get_ui (x, MPFR_RNDN);
    500          1.1       mrg 
    501          1.1       mrg   mpfr_set_str_binary (x, "0.1");
    502          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDN);
    503          1.1       mrg   MPFR_ASSERTN (dl == 0);
    504          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDZ);
    505          1.1       mrg   MPFR_ASSERTN (dl == 0);
    506          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDD);
    507          1.1       mrg   MPFR_ASSERTN (dl == 0);
    508          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDU);
    509          1.1       mrg   MPFR_ASSERTN (dl == 1);
    510          1.1       mrg 
    511          1.1       mrg   /* coverage tests */
    512          1.1       mrg   mpfr_set_prec (x, 2);
    513          1.1       mrg   mpfr_set_si (x, -7, MPFR_RNDD);
    514          1.1       mrg   MPFR_ASSERTN(mpfr_cmp_si (x, -8) == 0);
    515          1.1       mrg   mpfr_set_prec (x, 2);
    516          1.1       mrg   mpfr_set_ui (x, 7, MPFR_RNDU);
    517          1.1       mrg   MPFR_ASSERTN(mpfr_cmp_ui (x, 8) == 0);
    518          1.1       mrg   emax = mpfr_get_emax ();
    519          1.1       mrg   set_emax (3);
    520          1.1       mrg   mpfr_set_ui (x, 7, MPFR_RNDU);
    521          1.1       mrg   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
    522          1.1       mrg   set_emax (1);
    523          1.1       mrg   MPFR_ASSERTN( mpfr_set_ui (x, 7, MPFR_RNDU) );
    524          1.1       mrg   MPFR_ASSERTN(mpfr_inf_p (x) && mpfr_sgn (x) > 0);
    525          1.1       mrg   set_emax (emax);
    526          1.1       mrg   mpfr_set_ui_2exp (x, 17, -50, MPFR_RNDN);
    527          1.1       mrg   MPFR_ASSERTN (mpfr_get_ui (x, MPFR_RNDD) == 0);
    528          1.1       mrg   MPFR_ASSERTN (mpfr_get_si (x, MPFR_RNDD) == 0);
    529          1.1       mrg 
    530  1.1.1.3.2.1  pgoyette   /* Test for ERANGE flag + correct behavior if overflow */
    531          1.1       mrg   mpfr_set_prec (x, 256);
    532          1.1       mrg   mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
    533          1.1       mrg   mpfr_clear_erangeflag ();
    534          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDN);
    535          1.1       mrg   if (dl != ULONG_MAX || mpfr_erangeflag_p ())
    536          1.1       mrg     {
    537          1.1       mrg       printf ("ERROR for get_ui + ERANGE + ULONG_MAX (1)\n");
    538          1.1       mrg       exit (1);
    539          1.1       mrg     }
    540          1.1       mrg   mpfr_add_ui (x, x, 1, MPFR_RNDN);
    541          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDN);
    542          1.1       mrg   if (dl != ULONG_MAX || !mpfr_erangeflag_p ())
    543          1.1       mrg     {
    544          1.1       mrg       printf ("ERROR for get_ui + ERANGE + ULONG_MAX (2)\n");
    545          1.1       mrg       exit (1);
    546          1.1       mrg     }
    547          1.1       mrg   mpfr_set_si (x, -1, MPFR_RNDN);
    548          1.1       mrg   mpfr_clear_erangeflag ();
    549          1.1       mrg   dl = mpfr_get_ui (x, MPFR_RNDN);
    550          1.1       mrg   if (dl != 0 || !mpfr_erangeflag_p ())
    551          1.1       mrg     {
    552          1.1       mrg       printf ("ERROR for get_ui + ERANGE + -1 \n");
    553          1.1       mrg       exit (1);
    554          1.1       mrg     }
    555          1.1       mrg   mpfr_set_si (x, LONG_MAX, MPFR_RNDN);
    556          1.1       mrg   mpfr_clear_erangeflag ();
    557          1.1       mrg   d = mpfr_get_si (x, MPFR_RNDN);
    558          1.1       mrg   if (d != LONG_MAX || mpfr_erangeflag_p ())
    559          1.1       mrg     {
    560          1.1       mrg       printf ("ERROR for get_si + ERANGE + LONG_MAX (1): %ld\n", d);
    561          1.1       mrg       exit (1);
    562          1.1       mrg     }
    563          1.1       mrg   mpfr_add_ui (x, x, 1, MPFR_RNDN);
    564          1.1       mrg   d = mpfr_get_si (x, MPFR_RNDN);
    565          1.1       mrg   if (d != LONG_MAX || !mpfr_erangeflag_p ())
    566          1.1       mrg     {
    567          1.1       mrg       printf ("ERROR for get_si + ERANGE + LONG_MAX (2)\n");
    568          1.1       mrg       exit (1);
    569          1.1       mrg     }
    570          1.1       mrg   mpfr_set_si (x, LONG_MIN, MPFR_RNDN);
    571          1.1       mrg   mpfr_clear_erangeflag ();
    572          1.1       mrg   d = mpfr_get_si (x, MPFR_RNDN);
    573          1.1       mrg   if (d != LONG_MIN || mpfr_erangeflag_p ())
    574          1.1       mrg     {
    575          1.1       mrg       printf ("ERROR for get_si + ERANGE + LONG_MIN (1)\n");
    576          1.1       mrg       exit (1);
    577          1.1       mrg     }
    578          1.1       mrg   mpfr_sub_ui (x, x, 1, MPFR_RNDN);
    579          1.1       mrg   d = mpfr_get_si (x, MPFR_RNDN);
    580          1.1       mrg   if (d != LONG_MIN || !mpfr_erangeflag_p ())
    581          1.1       mrg     {
    582          1.1       mrg       printf ("ERROR for get_si + ERANGE + LONG_MIN (2)\n");
    583          1.1       mrg       exit (1);
    584          1.1       mrg     }
    585          1.1       mrg 
    586          1.1       mrg   mpfr_set_nan (x);
    587  1.1.1.3.2.1  pgoyette   mpfr_clear_flags ();
    588          1.1       mrg   d = mpfr_get_ui (x, MPFR_RNDN);
    589  1.1.1.3.2.1  pgoyette   if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
    590          1.1       mrg     {
    591          1.1       mrg       printf ("ERROR for get_ui + NaN\n");
    592          1.1       mrg       exit (1);
    593          1.1       mrg     }
    594          1.1       mrg   mpfr_clear_erangeflag ();
    595          1.1       mrg   d = mpfr_get_si (x, MPFR_RNDN);
    596  1.1.1.3.2.1  pgoyette   if (d != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
    597          1.1       mrg     {
    598          1.1       mrg       printf ("ERROR for get_si + NaN\n");
    599          1.1       mrg       exit (1);
    600          1.1       mrg     }
    601          1.1       mrg 
    602          1.1       mrg   emin = mpfr_get_emin ();
    603          1.1       mrg   mpfr_set_prec (x, 2);
    604          1.1       mrg 
    605          1.1       mrg   mpfr_set_emin (4);
    606          1.1       mrg   mpfr_clear_flags ();
    607          1.1       mrg   mpfr_set_ui (x, 7, MPFR_RNDU);
    608          1.1       mrg   flag = mpfr_underflow_p ();
    609          1.1       mrg   mpfr_set_emin (emin);
    610          1.1       mrg   if (mpfr_cmp_ui (x, 8) != 0)
    611          1.1       mrg     {
    612          1.1       mrg       printf ("Error for mpfr_set_ui (x, 7, MPFR_RNDU), prec = 2, emin = 4\n");
    613          1.1       mrg       exit (1);
    614          1.1       mrg     }
    615          1.1       mrg   if (flag)
    616          1.1       mrg     {
    617          1.1       mrg       printf ("mpfr_set_ui (x, 7, MPFR_RNDU) should not underflow "
    618          1.1       mrg               "with prec = 2, emin = 4\n");
    619          1.1       mrg       exit (1);
    620          1.1       mrg     }
    621          1.1       mrg 
    622          1.1       mrg   mpfr_set_emin (4);
    623          1.1       mrg   mpfr_clear_flags ();
    624          1.1       mrg   mpfr_set_si (x, -7, MPFR_RNDD);
    625          1.1       mrg   flag = mpfr_underflow_p ();
    626          1.1       mrg   mpfr_set_emin (emin);
    627          1.1       mrg   if (mpfr_cmp_si (x, -8) != 0)
    628          1.1       mrg     {
    629          1.1       mrg       printf ("Error for mpfr_set_si (x, -7, MPFR_RNDD), prec = 2, emin = 4\n");
    630          1.1       mrg       exit (1);
    631          1.1       mrg     }
    632          1.1       mrg   if (flag)
    633          1.1       mrg     {
    634          1.1       mrg       printf ("mpfr_set_si (x, -7, MPFR_RNDD) should not underflow "
    635          1.1       mrg               "with prec = 2, emin = 4\n");
    636          1.1       mrg       exit (1);
    637          1.1       mrg     }
    638          1.1       mrg 
    639          1.1       mrg   mpfr_clear (x);
    640          1.1       mrg 
    641          1.1       mrg   test_2exp ();
    642          1.1       mrg   test_macros ();
    643      1.1.1.2       mrg   test_macros_keyword ();
    644  1.1.1.3.2.1  pgoyette   test_get_ui_smallneg ();
    645          1.1       mrg   tests_end_mpfr ();
    646          1.1       mrg   return 0;
    647          1.1       mrg }
    648