(root)/
mpfr-4.2.1/
tests/
tset_sj.c
       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-2023 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                mpfr_clear_flags ();
     229                if (j == 0)
     230                  goto zero;
     231                e = MPFR_GET_EXP (x1);
     232                if (ep[i] < __gmpfr_emin - e)  /* underflow */
     233                  {
     234                    mpfr_rnd_t r =
     235                      (rnd == MPFR_RNDN &&
     236                       (ep[i] < __gmpfr_emin - MPFR_GET_EXP (y) - 1 ||
     237                        IS_POW2 (sign * j))) ?
     238                      MPFR_RNDZ : (mpfr_rnd_t) rnd;
     239                    inex1 = mpfr_underflow (x1, r, sign);
     240                    flags1 = __gmpfr_flags;
     241                  }
     242                else if (ep[i] > __gmpfr_emax - e)  /* overflow */
     243                  {
     244                    inex1 = mpfr_overflow (x1, (mpfr_rnd_t) rnd, sign);
     245                    flags1 = __gmpfr_flags;
     246                  }
     247                else
     248                  {
     249                    mpfr_set_exp (x1, ep[i] + e);
     250                  zero:
     251                    flags1 = inex1 != 0 ? MPFR_FLAGS_INEXACT : 0;
     252                  }
     253              }
     254  
     255            /* Test mpfr_set_sj_2exp */
     256            mpfr_clear_flags ();
     257            inex2 = mpfr_set_sj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
     258            flags2 = __gmpfr_flags;
     259  
     260            if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
     261                   mpfr_equal_p (x1, x2)))
     262              {
     263                s = 's';
     264                goto err_extreme;
     265              }
     266  
     267            if (j < 0)
     268              continue;
     269  
     270            /* Test mpfr_set_uj_2exp */
     271            mpfr_clear_flags ();
     272            inex2 = mpfr_set_uj_2exp (x2, j, em, (mpfr_rnd_t) rnd);
     273            flags2 = __gmpfr_flags;
     274  
     275            if (! (flags1 == flags2 && SAME_SIGN (inex1, inex2) &&
     276                   mpfr_equal_p (x1, x2)))
     277              {
     278                s = 'u';
     279              err_extreme:
     280                printf ("Error in extreme mpfr_set_%cj_2exp for i=%d j=%d %s\n",
     281                        s, i, j, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
     282                printf ("emin=%" MPFR_EXP_FSPEC "d "
     283                        "emax=%" MPFR_EXP_FSPEC "d\n",
     284                        (mpfr_eexp_t) __gmpfr_emin,
     285                        (mpfr_eexp_t) __gmpfr_emax);
     286  #ifndef NPRINTF_J
     287                printf ("e = %jd\n", em);
     288  #endif
     289                printf ("Expected ");
     290                mpfr_dump (x1);
     291                printf ("with inex = %d and flags =", inex1);
     292                flags_out (flags1);
     293                printf ("Got      ");
     294                mpfr_dump (x2);
     295                printf ("with inex = %d and flags =", inex2);
     296                flags_out (flags2);
     297                exit (1);
     298              }
     299          }
     300  
     301    mpfr_clears (x1, x2, y, (mpfr_ptr) 0);
     302  }
     303  
     304  static void
     305  test_2exp_extreme (void)
     306  {
     307    mpfr_exp_t emin, emax;
     308  
     309    emin = mpfr_get_emin ();
     310    emax = mpfr_get_emax ();
     311  
     312    set_emin (MPFR_EMIN_MIN);
     313    set_emax (MPFR_EMAX_MAX);
     314    test_2exp_extreme_aux ();
     315  
     316    set_emin (-REXP);
     317    set_emax (REXP);
     318    test_2exp_extreme_aux ();
     319  
     320    set_emin (emin);
     321    set_emax (emax);
     322  }
     323  
     324  int
     325  main (int argc, char *argv[])
     326  {
     327    tests_start_mpfr ();
     328  
     329    check_set_uj (2, 128, 50);
     330    check_set_uj_2exp ();
     331    check_set_sj ();
     332    check_set_sj_2exp ();
     333    test_2exp_extreme ();
     334  
     335    tests_end_mpfr ();
     336    return 0;
     337  }
     338  
     339  #endif