(root)/
mpfr-4.2.1/
tests/
tlog10.c
       1  /* Test file for mpfr_log10.
       2  
       3  Copyright 2001-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  #ifdef CHECK_EXTERNAL
      26  static int
      27  test_log10 (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
      28  {
      29    int res;
      30    int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
      31    if (ok)
      32      {
      33        mpfr_print_raw (b);
      34      }
      35    res = mpfr_log10 (a, b, rnd_mode);
      36    if (ok)
      37      {
      38        printf (" ");
      39        mpfr_print_raw (a);
      40        printf ("\n");
      41      }
      42    return res;
      43  }
      44  #else
      45  #define test_log10 mpfr_log10
      46  #endif
      47  
      48  #define TEST_FUNCTION test_log10
      49  #define TEST_RANDOM_POS 8
      50  #include "tgeneric.c"
      51  
      52  /* On 2023-02-13, one gets an infinite loop in mpfr_log10 on both
      53     32-bit and 64-bit hosts when the precision is not large enough
      54     (precision 12 and below). */
      55  static void
      56  bug20230213 (void)
      57  {
      58    mpfr_exp_t old_emin, old_emax, e;
      59    mpfr_t t, x, y0, y1, y2;
      60    int prec;
      61  
      62    old_emin = mpfr_get_emin ();
      63    old_emax = mpfr_get_emax ();
      64  
      65    set_emin (MPFR_EMIN_MIN);
      66    set_emax (MPFR_EMAX_MAX);
      67    e = mpfr_get_emax () - 1;
      68  
      69    /* The precisions of t and y0 should be large enough to avoid
      70       a hard-to-round case for the target precisions. */
      71    mpfr_inits2 (64, t, y0, (mpfr_ptr) 0);
      72    mpfr_set_exp_t (y0, e, MPFR_RNDN);
      73    mpfr_log_ui (t, 10, MPFR_RNDN);
      74    mpfr_div (y0, y0, t, MPFR_RNDN);
      75    mpfr_log_ui (t, 2, MPFR_RNDN);
      76    mpfr_mul (y0, y0, t, MPFR_RNDN);
      77  
      78    for (prec = 16; prec >= MPFR_PREC_MIN; prec--)
      79      {
      80        mpfr_inits2 (prec, x, y1, y2, (mpfr_ptr) 0);
      81        mpfr_set (y1, y0, MPFR_RNDN);
      82  
      83        mpfr_set_ui_2exp (x, 1, e, MPFR_RNDN);
      84        mpfr_log10 (y2, x, MPFR_RNDN);
      85        MPFR_ASSERTN (MPFR_IS_PURE_FP (y2));
      86        MPFR_ASSERTN (MPFR_IS_POS (y2));
      87  
      88        if (! mpfr_equal_p (y1, y2))
      89          {
      90            printf ("Error in bug20230213.\n");
      91            printf ("Expected ");
      92            mpfr_dump (y1);
      93            printf ("Got      ");
      94            mpfr_dump (y2);
      95            exit (1);
      96          }
      97        mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
      98      }
      99  
     100    mpfr_clears (t, y0, (mpfr_ptr) 0);
     101  
     102    set_emin (old_emin);
     103    set_emax (old_emax);
     104  }
     105  
     106  int
     107  main (int argc, char *argv[])
     108  {
     109    mpfr_t x, y;
     110    unsigned int n;
     111    int inex, r;
     112  
     113    tests_start_mpfr ();
     114  
     115    test_generic (MPFR_PREC_MIN, 100, 20);
     116  
     117    mpfr_init2 (x, 53);
     118    mpfr_init2 (y, 53);
     119  
     120    RND_LOOP (r)
     121      {
     122        /* check NaN */
     123        mpfr_set_nan (x);
     124        inex = test_log10 (y, x, (mpfr_rnd_t) r);
     125        MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
     126  
     127        /* check Inf */
     128        mpfr_set_inf (x, -1);
     129        inex = test_log10 (y, x, (mpfr_rnd_t) r);
     130        MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
     131  
     132        mpfr_set_inf (x, 1);
     133        inex = test_log10 (y, x, (mpfr_rnd_t) r);
     134        MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0 && inex == 0);
     135  
     136        mpfr_set_ui (x, 0, MPFR_RNDN);
     137        inex = test_log10 (x, x, (mpfr_rnd_t) r);
     138        MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
     139        mpfr_set_ui (x, 0, MPFR_RNDN);
     140        mpfr_neg (x, x, MPFR_RNDN);
     141        inex = test_log10 (x, x, (mpfr_rnd_t) r);
     142        MPFR_ASSERTN (mpfr_inf_p (x) && mpfr_sgn (x) < 0 && inex == 0);
     143  
     144        /* check negative argument */
     145        mpfr_set_si (x, -1, MPFR_RNDN);
     146        inex = test_log10 (y, x, (mpfr_rnd_t) r);
     147        MPFR_ASSERTN (mpfr_nan_p (y) && inex == 0);
     148  
     149        /* check log10(1) = 0 */
     150        mpfr_set_ui (x, 1, MPFR_RNDN);
     151        inex = test_log10 (y, x, (mpfr_rnd_t) r);
     152        MPFR_ASSERTN (MPFR_IS_ZERO (y) && MPFR_IS_POS (y) && inex == 0);
     153  
     154        /* check log10(10^n)=n */
     155        mpfr_set_ui (x, 1, MPFR_RNDN);
     156        for (n = 1; n <= 15; n++)
     157          {
     158            mpfr_mul_ui (x, x, 10, MPFR_RNDN); /* x = 10^n */
     159            inex = test_log10 (y, x, (mpfr_rnd_t) r);
     160            if (mpfr_cmp_ui (y, n))
     161              {
     162                printf ("log10(10^n) <> n for n=%u\n", n);
     163                exit (1);
     164              }
     165            MPFR_ASSERTN (inex == 0);
     166          }
     167      }
     168  
     169    mpfr_clear (x);
     170    mpfr_clear (y);
     171  
     172    bug20230213 ();
     173  
     174    data_check ("data/log10", mpfr_log10, "mpfr_log10");
     175    bad_cases (mpfr_log10, mpfr_exp10, "mpfr_log10",
     176               256, -30, 30, 4, 128, 800, 50);
     177  
     178    tests_end_mpfr ();
     179    return 0;
     180  }