(root)/
mpfr-4.2.1/
tests/
tui_div.c
       1  /* Test file for mpfr_ui_div.
       2  
       3  Copyright 2000-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  /* checks that y/x gives the right result with 53 bits of precision */
      26  static void
      27  check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs)
      28  {
      29    mpfr_t xx, zz;
      30  
      31    mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
      32    mpfr_set_str1 (xx, xs);
      33    mpfr_ui_div (zz, y, xx, rnd_mode);
      34    if (mpfr_cmp_str1(zz, zs))
      35      {
      36        printf ("expected quotient is %s, got ", zs);
      37        mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN);
      38        printf ("mpfr_ui_div failed for y=%lu x=%s with rnd_mode=%s\n",
      39                y, xs, mpfr_print_rnd_mode (rnd_mode));
      40        exit (1);
      41      }
      42    mpfr_clears (xx, zz, (mpfr_ptr) 0);
      43  }
      44  
      45  static void
      46  check_inexact (void)
      47  {
      48    mpfr_t x, y, z;
      49    mpfr_prec_t px, py;
      50    int inexact, cmp;
      51    unsigned long int u;
      52    int rnd;
      53  
      54    mpfr_init (x);
      55    mpfr_init (y);
      56    mpfr_init (z);
      57  
      58    for (px = MPFR_PREC_MIN; px < 300; px++)
      59      {
      60        mpfr_set_prec (x, px);
      61        do
      62          {
      63            mpfr_urandomb (x, RANDS);
      64          }
      65        while (mpfr_cmp_ui (x, 0) == 0);
      66        u = randlimb ();
      67        for (py = MPFR_PREC_MIN; py < 300; py++)
      68          {
      69            mpfr_set_prec (y, py);
      70            mpfr_set_prec (z, py + px);
      71            RND_LOOP (rnd)
      72              {
      73                inexact = mpfr_ui_div (y, u, x, (mpfr_rnd_t) rnd);
      74                if (mpfr_mul (z, y, x, (mpfr_rnd_t) rnd))
      75                  {
      76                    printf ("z <- y * x should be exact\n");
      77                    exit (1);
      78                  }
      79                cmp = mpfr_cmp_ui (z, u);
      80                if (rnd != MPFR_RNDF && ! SAME_SIGN (inexact, cmp))
      81                  {
      82                    printf ("Wrong inexact flag for u=%lu, rnd=%s\n",
      83                            u, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
      84                    printf ("expected %d, got %d\n", cmp, inexact);
      85                    printf ("x = "); mpfr_dump (x);
      86                    printf ("y = "); mpfr_dump (y);
      87                    printf ("y*x = "); mpfr_dump (z);
      88                    exit (1);
      89                  }
      90              }
      91          }
      92      }
      93  
      94    mpfr_clear (x);
      95    mpfr_clear (y);
      96    mpfr_clear (z);
      97  }
      98  
      99  static void
     100  check_special (void)
     101  {
     102    mpfr_t  d, q;
     103  
     104    mpfr_init2 (d, 100L);
     105    mpfr_init2 (q, 100L);
     106  
     107    /* 1/+inf == +0 */
     108    MPFR_SET_INF (d);
     109    MPFR_SET_POS (d);
     110    mpfr_clear_flags ();
     111    MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
     112    MPFR_ASSERTN (MPFR_IS_ZERO (q) && MPFR_IS_POS (q));
     113    MPFR_ASSERTN (__gmpfr_flags == 0);
     114  
     115    /* 1/-inf == -0 */
     116    MPFR_SET_INF (d);
     117    MPFR_SET_NEG (d);
     118    mpfr_clear_flags ();
     119    MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
     120    MPFR_ASSERTN (MPFR_IS_ZERO (q) && MPFR_IS_NEG (q));
     121    MPFR_ASSERTN (__gmpfr_flags == 0);
     122  
     123    /* 1/nan == nan */
     124    MPFR_SET_NAN (d);
     125    mpfr_clear_flags ();
     126    MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
     127    MPFR_ASSERTN (mpfr_nan_p (q));
     128    MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
     129  
     130    /* 0/0 == nan */
     131    mpfr_set_ui (d, 0L, MPFR_RNDN);
     132    mpfr_clear_flags ();
     133    MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
     134    MPFR_ASSERTN (mpfr_nan_p (q));
     135    MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_NAN);
     136  
     137    /* 1/+0 = +inf */
     138    mpfr_set_ui (d, 0L, MPFR_RNDN);
     139    mpfr_clear_flags ();
     140    MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
     141    MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) > 0);
     142    MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
     143  
     144    /* 1/-0 = -inf */
     145    mpfr_set_ui (d, 0L, MPFR_RNDN);
     146    mpfr_neg (d, d, MPFR_RNDN);
     147    mpfr_clear_flags ();
     148    MPFR_ASSERTN (mpfr_ui_div (q, 1L, d, MPFR_RNDZ) == 0); /* exact */
     149    MPFR_ASSERTN (mpfr_inf_p (q) && mpfr_sgn (q) < 0);
     150    MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_DIVBY0);
     151  
     152    /* 0/1 = +0 */
     153    mpfr_set_ui (d, 1L, MPFR_RNDN);
     154    mpfr_clear_flags ();
     155    MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
     156    MPFR_ASSERTN (MPFR_IS_ZERO (q) && MPFR_IS_POS (q));
     157    MPFR_ASSERTN (__gmpfr_flags == 0);
     158  
     159    /* 0/-1 = -0 */
     160    mpfr_set_si (d, -1, MPFR_RNDN);
     161    mpfr_clear_flags ();
     162    MPFR_ASSERTN (mpfr_ui_div (q, 0L, d, MPFR_RNDZ) == 0); /* exact */
     163    MPFR_ASSERTN (MPFR_IS_ZERO (q) && MPFR_IS_NEG (q));
     164    MPFR_ASSERTN (__gmpfr_flags == 0);
     165  
     166    mpfr_clear (d);
     167    mpfr_clear (q);
     168  }
     169  
     170  static int
     171  mpfr_inv (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
     172  {
     173    return mpfr_ui_div (y, 1, x, r);
     174  }
     175  
     176  static void
     177  check_overflow (void)
     178  {
     179    mpfr_exp_t emin, emax;
     180    mpfr_t x, y1, y2;
     181    int inex1, inex2, rnd_mode;
     182    mpfr_flags_t flags1, flags2;
     183  
     184    emin = mpfr_get_emin ();
     185    emax = mpfr_get_emax ();
     186    set_emin (MPFR_EMIN_MIN);
     187    set_emax (MPFR_EMAX_MAX);
     188  
     189    mpfr_inits2 (32, x, y1, y2, (mpfr_ptr) 0);
     190    mpfr_setmin (x, MPFR_EMIN_MIN);
     191    RND_LOOP (rnd_mode)
     192      {
     193        inex1 = mpfr_overflow (y1, (mpfr_rnd_t) rnd_mode, 1);
     194        flags1 = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
     195        mpfr_clear_flags ();
     196        inex2 = mpfr_ui_div (y2, 1, x, (mpfr_rnd_t) rnd_mode);
     197        flags2 = __gmpfr_flags;
     198        if (!(mpfr_equal_p (y1, y2) &&
     199              SAME_SIGN (inex1, inex2) &&
     200              flags1 == flags2))
     201          {
     202            printf ("Error in check_overflow for %s\n",
     203                    mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode));
     204            printf ("Expected ");
     205            mpfr_dump (y1);
     206            printf ("  with inex = %d, flags =", inex1);
     207            flags_out (flags1);
     208            printf ("Got      ");
     209            mpfr_dump (y2);
     210            printf ("  with inex = %d, flags =", inex2);
     211            flags_out (flags2);
     212            exit (1);
     213          }
     214      }
     215    mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
     216  
     217    set_emin (emin);
     218    set_emax (emax);
     219  }
     220  
     221  #define TEST_FUNCTION mpfr_ui_div
     222  #define ULONG_ARG1
     223  #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
     224  #include "tgeneric.c"
     225  
     226  int
     227  main (int argc, char *argv[])
     228  {
     229    tests_start_mpfr ();
     230  
     231    check_special ();
     232    check_inexact ();
     233    check(948002822, "1.22191250737771397120e+20", MPFR_RNDN,
     234          "7.758352715731357946e-12");
     235    check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ,
     236          "1.5772563211925444801e-223");
     237    check(740454110, "2.11496253355831863313e+183", MPFR_RNDZ,
     238          "3.5010270784996976041e-175");
     239    check(1690540942, "1.28278599852446657468e-276", MPFR_RNDU,
     240          "1.3178666932321966062e285");
     241    check(1476599377, "-2.14191393656148625995e+305", MPFR_RNDD,
     242          "-6.8938315017943889615e-297");
     243    check_overflow ();
     244  
     245    test_generic (MPFR_PREC_MIN, 1000, 100);
     246  
     247    /* inv is for 1/x */
     248    data_check ("data/inv", mpfr_inv, "mpfr_ui_div(1,x)");
     249  
     250    tests_end_mpfr ();
     251    return 0;
     252  }