Home | History | Annotate | Line # | Download | only in tests
tset_sj.c revision 1.1.1.5
      1 /* Test file for
      2    mpfr_set_sj, mpfr_set_uj, mpfr_set_sj_2exp and mpfr_set_uj_2exp.
      3 
      4 Copyright 2004, 2006-2020 Free Software Foundation, Inc.
      5 Contributed by the AriC and Caramba projects, INRIA.
      6 
      7 This file is part of the GNU MPFR Library.
      8 
      9 The GNU MPFR Library is free software; you can redistribute it and/or modify
     10 it under the terms of the GNU Lesser General Public License as published by
     11 the Free Software Foundation; either version 3 of the License, or (at your
     12 option) any later version.
     13 
     14 The GNU MPFR Library is distributed in the hope that it will be useful, but
     15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     17 License for more details.
     18 
     19 You should have received a copy of the GNU Lesser General Public License
     20 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     23 
     24 #define MPFR_NEED_INTMAX_H
     25 #include "mpfr-test.h"
     26 
     27 #ifndef _MPFR_H_HAVE_INTMAX_T
     28 
     29 int
     30 main (void)
     31 {
     32   return 77;
     33 }
     34 
     35 #else
     36 
     37 #define PRINT_ERROR(str) \
     38   do { printf ("Error for %s\n", str); exit (1); } while (0)
     39 
     40 static int
     41 inexact_sign (int x)
     42 {
     43   return (x < 0) ? -1 : (x > 0);
     44 }
     45 
     46 static void
     47 check_set_uj (mpfr_prec_t pmin, mpfr_prec_t pmax, int N)
     48 {
     49   mpfr_t x, y;
     50   mpfr_prec_t p;
     51   int inex1, inex2, n;
     52   mp_limb_t limb;
     53 
     54   mpfr_inits2 (pmax, x, y, (mpfr_ptr) 0);
     55 
     56   for (p = pmin ; p < pmax ; p++)
     57     {
     58       mpfr_set_prec (x, p);
     59       mpfr_set_prec (y, p);
     60       for (n = 0 ; n < N ; n++)
     61         {
     62           /* mp_limb_t may be unsigned long long */
     63           limb = (unsigned long) randlimb ();
     64           inex1 = mpfr_set_uj (x, limb, MPFR_RNDN);
     65           inex2 = mpfr_set_ui (y, limb, MPFR_RNDN);
     66           if (mpfr_cmp (x, y))
     67             {
     68               printf ("ERROR for mpfr_set_uj and j=%lu and p=%lu\n",
     69                       (unsigned long) limb, (unsigned long) p);
     70               printf ("X="); mpfr_dump (x);
     71               printf ("Y="); mpfr_dump (y);
     72               exit (1);
     73             }
     74           if (inexact_sign (inex1) != inexact_sign (inex2))
     75             {
     76               printf ("ERROR for inexact(set_uj): j=%lu p=%lu\n"
     77                       "Inexact1= %d Inexact2= %d\n",
     78                       (unsigned long) limb, (unsigned long) p, inex1, inex2);
     79               exit (1);
     80             }
     81         }
     82     }
     83   /* Special case */
     84   mpfr_set_prec (x, sizeof(uintmax_t)*CHAR_BIT);
     85   inex1 = mpfr_set_uj (x, UINTMAX_MAX, MPFR_RNDN);
     86   if (inex1 != 0 || mpfr_sgn(x) <= 0)
     87     PRINT_ERROR ("inexact / UINTMAX_MAX");
     88   inex1 = mpfr_add_ui (x, x, 1, MPFR_RNDN);
     89   if (inex1 != 0 || !mpfr_powerof2_raw (x)
     90       || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
     91     PRINT_ERROR ("power of 2");
     92   mpfr_set_uj (x, 0, MPFR_RNDN);
     93   if (!MPFR_IS_ZERO (x))
     94     PRINT_ERROR ("Setting 0");
     95 
     96   mpfr_clears (x, y, (mpfr_ptr) 0);
     97 }
     98 
     99 static void
    100 check_set_uj_2exp (void)
    101 {
    102   mpfr_t x;
    103   int inex;
    104 
    105   mpfr_init2 (x, sizeof(uintmax_t)*CHAR_BIT);
    106 
    107   inex = mpfr_set_uj_2exp (x, 1, 0, MPFR_RNDN);
    108   if (inex || mpfr_cmp_ui(x, 1))
    109     PRINT_ERROR ("(1U,0)");
    110 
    111   inex = mpfr_set_uj_2exp (x, 1024, -10, MPFR_RNDN);
    112   if (inex || mpfr_cmp_ui(x, 1))
    113     PRINT_ERROR ("(1024U,-10)");
    114 
    115   inex = mpfr_set_uj_2exp (x, 1024, 10, MPFR_RNDN);
    116   if (inex || mpfr_cmp_ui(x, 1024L * 1024L))
    117     PRINT_ERROR ("(1024U,+10)");
    118 
    119   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, 1000, MPFR_RNDN);
    120   inex |= mpfr_div_2ui (x, x, 1000, MPFR_RNDN);
    121   inex |= mpfr_add_ui (x, x, 1, MPFR_RNDN);
    122   if (inex || !mpfr_powerof2_raw (x)
    123       || MPFR_EXP (x) != sizeof(uintmax_t) * CHAR_BIT + 1)
    124     PRINT_ERROR ("(UINTMAX_MAX)");
    125 
    126   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMAX_MAX-10, MPFR_RNDN);
    127   if (inex == 0 || !mpfr_inf_p (x))
    128     PRINT_ERROR ("Overflow");
    129 
    130   inex = mpfr_set_uj_2exp (x, UINTMAX_MAX, MPFR_EMIN_MIN-1000, MPFR_RNDN);
    131   if (inex == 0 || !MPFR_IS_ZERO (x))
    132     PRINT_ERROR ("Underflow");
    133 
    134   mpfr_clear (x);
    135 }
    136 
    137 static void
    138 check_set_sj (void)
    139 {
    140   mpfr_t x;
    141   int inex;
    142 
    143   mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
    144 
    145   inex = mpfr_set_sj (x, -INTMAX_MAX, MPFR_RNDN);
    146   inex |= mpfr_add_si (x, x, -1, MPFR_RNDN);
    147   if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
    148       || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT)
    149     PRINT_ERROR ("set_sj (-INTMAX_MAX)");
    150 
    151   inex = mpfr_set_sj (x, 1742, MPFR_RNDN);
    152   if (inex || mpfr_cmp_ui (x, 1742))
    153     PRINT_ERROR ("set_sj (1742)");
    154 
    155   mpfr_clear (x);
    156 }
    157 
    158 static void
    159 check_set_sj_2exp (void)
    160 {
    161   mpfr_t x;
    162   int inex;
    163 
    164   mpfr_init2 (x, sizeof(intmax_t)*CHAR_BIT-1);
    165 
    166   inex = mpfr_set_sj_2exp (x, INTMAX_MIN, 1000, MPFR_RNDN);
    167   if (inex || mpfr_sgn (x) >=0 || !mpfr_powerof2_raw (x)
    168       || MPFR_EXP (x) != sizeof(intmax_t) * CHAR_BIT + 1000)
    169     PRINT_ERROR ("set_sj_2exp (INTMAX_MIN)");
    170 
    171   mpfr_clear (x);
    172 }
    173 
    174 #define REXP 1024
    175 
    176 static void
    177 test_2exp_extreme_aux (void)
    178 {
    179   mpfr_t x1, x2, y;
    180   mpfr_exp_t e, ep[1 + 8 * 5], eb[] =
    181     { MPFR_EMIN_MIN, -REXP, REXP, MPFR_EMAX_MAX, MPFR_EXP_MAX };
    182   mpfr_flags_t flags1, flags2;
    183   int i, j, rnd, inex1, inex2;
    184   char s;
    185 
    186   ep[0] = MPFR_EXP_MIN;
    187   for (i = 0; i < numberof(eb); i++)
    188     for (j = 0; j < 8; j++)
    189       ep[1 + 8 * i + j] = eb[i] - j;
    190 
    191   mpfr_inits2 (3, x1, x2, (mpfr_ptr) 0);
    192   mpfr_init2 (y, 32);
    193 
    194   /* The cast to int is needed if numberof(ep) is of unsigned type, in
    195      which case the condition without the cast would be always false. */
    196   for (i = -2; i < (int) numberof(ep); i++)
    197     for (j = -31; j <= 31; j++)
    198       RND_LOOP_NO_RNDF (rnd)
    199         {
    200           int sign = j < 0 ? -1 : 1;
    201           intmax_t em;
    202 
    203           if (i < 0)
    204             {
    205               em = i == -2 ? INTMAX_MIN : INTMAX_MAX;
    206               mpfr_clear_flags ();
    207               inex1 = j == 0 ?
    208                 (mpfr_set_zero (x1, +1), 0) : i == -2 ?
    209                 mpfr_underflow (x1, rnd == MPFR_RNDN ?
    210                                 MPFR_RNDZ : (mpfr_rnd_t) rnd, sign) :
    211                 mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
    212               flags1 = __gmpfr_flags;
    213             }
    214           else
    215             {
    216               em = ep[i];
    217               /* Compute the expected value, inex and flags */
    218               inex1 = mpfr_set_si (y, j, MPFR_RNDN);
    219               MPFR_ASSERTN (inex1 == 0);
    220               inex1 = mpfr_set (x1, y, (mpfr_rnd_t) rnd);
    221               /* x1 is the rounded value and inex1 the ternary value,
    222                  assuming that the exponent argument is 0 (this is the
    223                  rounded significand of the final result, assuming an
    224                  unbounded exponent range). The multiplication by a
    225                  power of 2 is exact, unless underflow/overflow occurs.
    226                  The tests on the exponent below avoid integer overflows
    227                  (ep[i] may take extreme values). */
    228               e = mpfr_get_exp (x1);
    229               mpfr_clear_flags ();
    230               if (j != 0 && ep[i] < __gmpfr_emin - e)  /* underflow */
    231                 {
    232                   mpfr_rnd_t r =
    233                     (rnd == MPFR_RNDN &&
    234                      (ep[i] < __gmpfr_emin - mpfr_get_exp (y) - 1 ||
    235                       IS_POW2 (sign * j))) ?
    236                     MPFR_RNDZ : (mpfr_rnd_t) rnd;
    237                   inex1 = mpfr_underflow (x1, r, sign);
    238                   flags1 = __gmpfr_flags;
    239                 }
    240               else if (j != 0 && ep[i] > __gmpfr_emax - e)  /* overflow */
    241                 {
    242                   inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
    243                   flags1 = __gmpfr_flags;
    244                 }
    245               else
    246                 {
    247                   if (j != 0)
    248                     mpfr_set_exp (x1, ep[i] + e);
    249                   flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
    250                 }
    251             }
    252 
    253           /* Test mpfr_set_sj_2exp */
    254           mpfr_clear_flags ();
    255           inex2 = mpfr_set_sj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
    256           flags2 = __gmpfr_flags;
    257 
    258           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
    259                  mpfr_equal_p (x1, x2)))
    260             {
    261               s = 's';
    262               goto err_extreme;
    263             }
    264 
    265           if (j < 0)
    266             continue;
    267 
    268           /* Test mpfr_set_uj_2exp */
    269           mpfr_clear_flags ();
    270           inex2 = mpfr_set_uj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
    271           flags2 = __gmpfr_flags;
    272 
    273           if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
    274                  mpfr_equal_p (x1, x2)))
    275             {
    276               s = 'u';
    277             err_extreme:
    278               printf ("Error in extreme mpfr_set_%cj_2exp for i=%d j=%d %s\n",
    279                       s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
    280               printf ("emin=%" MPFR_EXP_FSPEC "d "
    281                       "emax=%" MPFR_EXP_FSPEC "d\n",
    282                       (mpfr_eexp_t) __gmpfr_emin,
    283                       (mpfr_eexp_t) __gmpfr_emax);
    284 #ifndef NPRINTF_J
    285               printf ("e = %jd\n", em);
    286 #endif
    287               printf ("Expected ");
    288               mpfr_dump (x1);
    289               printf ("with inex = %d and flags =", inex1);
    290               flags_out (flags1);
    291               printf ("Got      ");
    292               mpfr_dump (x2);
    293               printf ("with inex = %d and flags =", inex2);
    294               flags_out (flags2);
    295               exit (1);
    296             }
    297         }
    298 
    299   mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
    300 }
    301 
    302 static void
    303 test_2exp_extreme (void)
    304 {
    305   mpfr_exp_t emin, emax;
    306 
    307   emin = mpfr_get_emin ();
    308   emax = mpfr_get_emax ();
    309 
    310   set_emin (MPFR_EMIN_MIN);
    311   set_emax (MPFR_EMAX_MAX);
    312   test_2exp_extreme_aux ();
    313 
    314   set_emin (-REXP);
    315   set_emax (REXP);
    316   test_2exp_extreme_aux ();
    317 
    318   set_emin (emin);
    319   set_emax (emax);
    320 }
    321 
    322 int
    323 main (int argc, char *argv[])
    324 {
    325   tests_start_mpfr ();
    326 
    327   check_set_uj (2, 128, 50);
    328   check_set_uj_2exp ();
    329   check_set_sj ();
    330   check_set_sj_2exp ();
    331   test_2exp_extreme ();
    332 
    333   tests_end_mpfr ();
    334   return 0;
    335 }
    336 
    337 #endif
    338