(root)/
mpfr-4.2.1/
tests/
tfits.c
       1  /* Test file for:
       2   mpfr_fits_sint_p, mpfr_fits_slong_p, mpfr_fits_sshort_p,
       3   mpfr_fits_uint_p, mpfr_fits_ulong_p, mpfr_fits_ushort_p
       4  
       5  Copyright 2004-2023 Free Software Foundation, Inc.
       6  Contributed by the AriC and Caramba projects, INRIA.
       7  
       8  This file is part of the GNU MPFR Library.
       9  
      10  The GNU MPFR Library is free software; you can redistribute it and/or modify
      11  it under the terms of the GNU Lesser General Public License as published by
      12  the Free Software Foundation; either version 3 of the License, or (at your
      13  option) any later version.
      14  
      15  The GNU MPFR Library is distributed in the hope that it will be useful, but
      16  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      17  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      18  License for more details.
      19  
      20  You should have received a copy of the GNU Lesser General Public License
      21  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      22  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      23  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      24  
      25  #define MPFR_NEED_INTMAX_H
      26  #include "mpfr-test.h"
      27  
      28  #define FTEST_AUX(N,NOT,FCT)                                    \
      29    do                                                            \
      30      {                                                           \
      31        __gmpfr_flags = ex_flags;                                 \
      32        if (NOT FCT (x, (mpfr_rnd_t) r))                          \
      33          {                                                       \
      34            printf ("Error %d for %s, rnd = %s and x = ",         \
      35                    N, #FCT,                                      \
      36                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));        \
      37            mpfr_dump (x);                                        \
      38            exit (1);                                             \
      39          }                                                       \
      40        if (__gmpfr_flags != ex_flags)                            \
      41          {                                                       \
      42            mpfr_flags_t flags = __gmpfr_flags;                   \
      43            printf ("Flags error %d for %s, rnd = %s and x = ",   \
      44                    N, #FCT,                                      \
      45                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));        \
      46            mpfr_dump(x);                                         \
      47            printf ("Expected flags:");                           \
      48            flags_out (ex_flags);                                 \
      49            printf ("Got flags:     ");                           \
      50            flags_out (flags);                                    \
      51            exit (1);                                             \
      52          }                                                       \
      53      }                                                           \
      54    while (0)
      55  
      56  #define FTEST(N,NOT,FCT)                                        \
      57    do                                                            \
      58      {                                                           \
      59        mpfr_exp_t e;                                             \
      60        FTEST_AUX (N,NOT,FCT);                                    \
      61        if (MPFR_IS_SINGULAR (x))                                 \
      62          break;                                                  \
      63        e = mpfr_get_exp (x);                                     \
      64        set_emin (e);                                             \
      65        set_emax (e);                                             \
      66        FTEST_AUX (N,NOT,FCT);                                    \
      67        set_emin (emin);                                          \
      68        set_emax (emax);                                          \
      69      }                                                           \
      70    while (0)
      71  
      72  #define CHECK_ALL(N,NOT)                                        \
      73    do                                                            \
      74      {                                                           \
      75        FTEST (N, NOT, mpfr_fits_ulong_p);                        \
      76        FTEST (N, NOT, mpfr_fits_slong_p);                        \
      77        FTEST (N, NOT, mpfr_fits_uint_p);                         \
      78        FTEST (N, NOT, mpfr_fits_sint_p);                         \
      79        FTEST (N, NOT, mpfr_fits_ushort_p);                       \
      80        FTEST (N, NOT, mpfr_fits_sshort_p);                       \
      81      }                                                           \
      82    while (0)
      83  
      84  #define CHECK_MAX(N,NOT)                                        \
      85    do                                                            \
      86      {                                                           \
      87        FTEST (N, NOT, mpfr_fits_uintmax_p);                      \
      88        FTEST (N, NOT, mpfr_fits_intmax_p);                       \
      89      }                                                           \
      90    while (0)
      91  
      92  /* V is a non-zero limit for the type (*_MIN for a signed type or *_MAX).
      93   * If V is positive, then test V, V + 1/4, V + 3/4 and V + 1.
      94   * If V is negative, then test V, V - 1/4, V - 3/4 and V - 1.
      95   */
      96  #define CHECK_LIM(N,V,SET,FCT)                                  \
      97    do                                                            \
      98      {                                                           \
      99        SET (x, V, MPFR_RNDN);                                    \
     100        FTEST (N, !, FCT);                                        \
     101        mpfr_set_si_2exp (y, (V) < 0 ? -1 : 1, -2, MPFR_RNDN);    \
     102        mpfr_add (x, x, y, MPFR_RNDN);                            \
     103        FTEST (N+1, (r == MPFR_RNDN ||                            \
     104                     MPFR_IS_LIKE_RNDZ (r, (V) < 0)) ^ !!, FCT);  \
     105        mpfr_add (x, x, y, MPFR_RNDN);                            \
     106        mpfr_add (x, x, y, MPFR_RNDN);                            \
     107        FTEST (N+3, MPFR_IS_LIKE_RNDZ (r, (V) < 0) ^ !!, FCT);    \
     108        mpfr_add (x, x, y, MPFR_RNDN);                            \
     109        FTEST (N+4, !!, FCT);                                     \
     110      }                                                           \
     111    while (0)
     112  
     113  int
     114  main (void)
     115  {
     116    mpfr_exp_t emin, emax;
     117    mpfr_t x, y;
     118    mpfr_flags_t flags[2] = { 0, MPFR_FLAGS_ALL }, ex_flags;
     119    int i, r, fi;
     120  
     121    tests_start_mpfr ();
     122  
     123    emin = mpfr_get_emin ();
     124    emax = mpfr_get_emax ();
     125  
     126    mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 2);
     127    mpfr_init2 (y, 8);
     128  
     129    RND_LOOP (r)
     130      for (fi = 0; fi < numberof (flags); fi++)
     131        {
     132          ex_flags = flags[fi];
     133  
     134          /* Check NaN */
     135          mpfr_set_nan (x);
     136          CHECK_ALL (1, !!);
     137  
     138          /* Check +Inf */
     139          mpfr_set_inf (x, 1);
     140          CHECK_ALL (2, !!);
     141  
     142          /* Check -Inf */
     143          mpfr_set_inf (x, -1);
     144          CHECK_ALL (3, !!);
     145  
     146          /* Check +0 */
     147          mpfr_set_zero (x, 1);
     148          CHECK_ALL (4, !);
     149  
     150          /* Check -0 */
     151          mpfr_set_zero (x, -1);
     152          CHECK_ALL (5, !);
     153  
     154          /* Check small positive op */
     155          mpfr_set_str1 (x, "1@-1");
     156          CHECK_ALL (6, !);
     157  
     158          /* Check 17 */
     159          mpfr_set_ui (x, 17, MPFR_RNDN);
     160          CHECK_ALL (7, !);
     161  
     162          /* Check large values (no fit) */
     163          mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
     164          mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
     165          CHECK_ALL (8, !!);
     166          mpfr_mul_2ui (x, x, 40, MPFR_RNDN);
     167          CHECK_ALL (9, !!);
     168  
     169          /* Check a non-integer number just below a power of two. */
     170          mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
     171          CHECK_ALL (10, !);
     172  
     173          /* Check the limits of the types (except 0 for unsigned types) */
     174          CHECK_LIM (20, ULONG_MAX, mpfr_set_ui, mpfr_fits_ulong_p);
     175          CHECK_LIM (30, LONG_MAX, mpfr_set_si, mpfr_fits_slong_p);
     176          CHECK_LIM (35, LONG_MIN, mpfr_set_si, mpfr_fits_slong_p);
     177          CHECK_LIM (40, UINT_MAX, mpfr_set_ui, mpfr_fits_uint_p);
     178          CHECK_LIM (50, INT_MAX, mpfr_set_si, mpfr_fits_sint_p);
     179          CHECK_LIM (55, INT_MIN, mpfr_set_si, mpfr_fits_sint_p);
     180          CHECK_LIM (60, USHRT_MAX, mpfr_set_ui, mpfr_fits_ushort_p);
     181          CHECK_LIM (70, SHRT_MAX, mpfr_set_si, mpfr_fits_sshort_p);
     182          CHECK_LIM (75, SHRT_MIN, mpfr_set_si, mpfr_fits_sshort_p);
     183  
     184          /* Check negative op */
     185          for (i = 1; i <= 4; i++)
     186            {
     187              int inv;
     188  
     189              mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
     190              /* for RNDF, it fits if it fits when rounding away from zero */
     191              mpfr_rint (y, x, r != MPFR_RNDF ? (mpfr_rnd_t) r : MPFR_RNDA);
     192              inv = MPFR_NOTZERO (y);
     193              FTEST (80, inv ^ !, mpfr_fits_ulong_p);
     194              FTEST (81,       !, mpfr_fits_slong_p);
     195              FTEST (82, inv ^ !, mpfr_fits_uint_p);
     196              FTEST (83,       !, mpfr_fits_sint_p);
     197              FTEST (84, inv ^ !, mpfr_fits_ushort_p);
     198              FTEST (85,       !, mpfr_fits_sshort_p);
     199            }
     200        }
     201  
     202  #ifdef _MPFR_H_HAVE_INTMAX_T
     203  
     204    mpfr_set_prec (x, sizeof (uintmax_t) * CHAR_BIT + 2);
     205  
     206    RND_LOOP (r)
     207      {
     208        /* Check NaN */
     209        mpfr_set_nan (x);
     210        CHECK_MAX (1, !!);
     211  
     212        /* Check +Inf */
     213        mpfr_set_inf (x, 1);
     214        CHECK_MAX (2, !!);
     215  
     216        /* Check -Inf */
     217        mpfr_set_inf (x, -1);
     218        CHECK_MAX (3, !!);
     219  
     220        /* Check +0 */
     221        mpfr_set_zero (x, 1);
     222        CHECK_MAX (4, !);
     223  
     224        /* Check -0 */
     225        mpfr_set_zero (x, -1);
     226        CHECK_MAX (5, !);
     227  
     228        /* Check small positive op */
     229        mpfr_set_str1 (x, "1@-1");
     230        CHECK_MAX (6, !);
     231  
     232        /* Check 17 */
     233        mpfr_set_ui (x, 17, MPFR_RNDN);
     234        CHECK_MAX (7, !);
     235  
     236        /* Check hugest */
     237        mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
     238        CHECK_MAX (8, !!);
     239  
     240        /* Check a non-integer number just below a power of two. */
     241        mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
     242        CHECK_MAX (10, !);
     243  
     244        /* Check the limits of the types (except 0 for uintmax_t) */
     245        CHECK_LIM (20, UINTMAX_MAX, mpfr_set_uj, mpfr_fits_uintmax_p);
     246        CHECK_LIM (30, INTMAX_MAX, mpfr_set_sj, mpfr_fits_intmax_p);
     247        CHECK_LIM (35, INTMAX_MIN, mpfr_set_sj, mpfr_fits_intmax_p);
     248  
     249        /* Check negative op */
     250        for (i = 1; i <= 4; i++)
     251          {
     252            int inv;
     253  
     254            mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
     255            mpfr_rint (y, x, (mpfr_rnd_t) r);
     256            inv = MPFR_NOTZERO (y);
     257            if (r != MPFR_RNDF)
     258              FTEST (80, inv ^ !, mpfr_fits_uintmax_p);
     259            else
     260              FTEST (80, !!, mpfr_fits_uintmax_p);
     261            FTEST (81,       !, mpfr_fits_intmax_p);
     262          }
     263      }
     264  
     265  #endif  /* _MPFR_H_HAVE_INTMAX_T */
     266  
     267    mpfr_clear (x);
     268    mpfr_clear (y);
     269  
     270    tests_end_mpfr ();
     271    return 0;
     272  }