(root)/
mpfr-4.2.1/
tests/
ttan.c
       1  /* Test file for mpfr_tan.
       2  
       3  Copyright 2001-2004, 2006-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  #define TEST_FUNCTION mpfr_tan
      26  #define REDUCE_EMAX 262143 /* otherwise arg. reduction is too expensive */
      27  #include "tgeneric.c"
      28  
      29  static void
      30  check_nans (void)
      31  {
      32    mpfr_t  x, y;
      33  
      34    mpfr_init2 (x, 123L);
      35    mpfr_init2 (y, 123L);
      36  
      37    mpfr_set_nan (x);
      38    mpfr_tan (y, x, MPFR_RNDN);
      39    if (! mpfr_nan_p (y))
      40      {
      41        printf ("Error: tan(NaN) != NaN\n");
      42        exit (1);
      43      }
      44  
      45    mpfr_set_inf (x, 1);
      46    mpfr_tan (y, x, MPFR_RNDN);
      47    if (! mpfr_nan_p (y))
      48      {
      49        printf ("Error: tan(Inf) != NaN\n");
      50        exit (1);
      51      }
      52  
      53    mpfr_set_inf (x, -1);
      54    mpfr_tan (y, x, MPFR_RNDN);
      55    if (! mpfr_nan_p (y))
      56      {
      57        printf ("Error: tan(-Inf) != NaN\n");
      58        exit (1);
      59      }
      60  
      61    /* exercise recomputation */
      62    mpfr_set_prec (x, 14);
      63    mpfr_set_str_binary (x, "0.10100000101010E0");
      64    mpfr_set_prec (y, 24);
      65    mpfr_tan (y, x, MPFR_RNDU);
      66    mpfr_set_prec (x, 24);
      67    mpfr_set_str_binary (x, "101110011011001100100001E-24");
      68    MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
      69  
      70    /* Compute ~Pi/2 to check overflow */
      71    mpfr_set_prec (x, 20000);
      72    mpfr_const_pi (x, MPFR_RNDD);
      73    mpfr_div_2ui (x, x, 1, MPFR_RNDN);
      74    mpfr_set_prec (y, 24);
      75    mpfr_tan (y, x, MPFR_RNDN);
      76    if (mpfr_cmp_str (y, "0.100011101101011000100011E20001", 2, MPFR_RNDN))
      77      {
      78        printf("Error computing tan(~Pi/2)\n");
      79        mpfr_dump (y);
      80        exit (1);
      81      }
      82  
      83    /* bug found by Kaveh Ghazi on 13 Jul 2007 */
      84    mpfr_set_prec (x, 53);
      85    mpfr_set_prec (y, 53);
      86    mpfr_set_str_binary (x, "0.10011100110111000001000010110100101000000000000000000E34");
      87    mpfr_tan (y, x, MPFR_RNDN);
      88    mpfr_set_str_binary (x, "0.1000010011001010001000010100000110100111000011010101E41");
      89    MPFR_ASSERTN(mpfr_cmp (x, y) == 0);
      90  
      91    mpfr_clear (x);
      92    mpfr_clear (y);
      93  }
      94  
      95  /* This test was generated from bad_cases, with GMP_CHECK_RANDOMIZE=1514257254.
      96     For the x value below, we have tan(x) = -1.875 + epsilon,
      97     thus with RNDZ it should be rounded to -1.c. */
      98  static void
      99  bug20171218 (void)
     100  {
     101    mpfr_t x, y, z;
     102    mpfr_init2 (x, 804);
     103    mpfr_init2 (y, 4);
     104    mpfr_init2 (z, 4);
     105    mpfr_set_str (x, "-1.14b1dd5f90ce0eded2a8f59c05e72daf7cc4c78f5075d73246fa420e2c026291d9377e67e7f54e925c4aed39c7b2f917424033c8612f00a19821890558d6c2cef9c60f4ad2c3b061ed53a1709dc1ec8e139627c2119c36d7ebdff0d715e559b47f740c534", 16, MPFR_RNDN);
     106    mpfr_tan (y, x, MPFR_RNDZ);
     107    mpfr_set_str (z, "-1.c", 16, MPFR_RNDN);
     108    MPFR_ASSERTN(mpfr_equal_p (y, z));
     109    mpfr_clear (x);
     110    mpfr_clear (y);
     111    mpfr_clear (z);
     112  }
     113  
     114  static void
     115  coverage (void)
     116  {
     117    mpfr_t x, y;
     118    int inex;
     119    mpfr_exp_t emax;
     120  
     121    /* exercise mpfr_round_near_x when rounding gives an overflow */
     122    emax = mpfr_get_emax ();
     123    set_emax (-2);
     124    mpfr_init2 (x, 2);
     125    mpfr_init2 (y, 2);
     126    mpfr_setmax (x, mpfr_get_emax ());
     127    inex = mpfr_tan (y, x, MPFR_RNDA);
     128    MPFR_ASSERTN(inex > 0);
     129    MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_signbit (y) == 0);
     130    mpfr_clear (x);
     131    mpfr_clear (y);
     132    set_emax (emax);
     133  }
     134  
     135  int
     136  main (int argc, char *argv[])
     137  {
     138    mpfr_t x;
     139    unsigned int i;
     140    unsigned int prec[10] = {14, 15, 19, 22, 23, 24, 25, 40, 41, 52};
     141    unsigned int prec2[10] = {4, 5, 6, 19, 70, 95, 100, 106, 107, 108};
     142  
     143    tests_start_mpfr ();
     144  
     145    coverage ();
     146    bug20171218 ();
     147    check_nans ();
     148  
     149    mpfr_init (x);
     150  
     151    mpfr_set_prec (x, 2);
     152    mpfr_set_str (x, "0.5", 10, MPFR_RNDN);
     153    mpfr_tan (x, x, MPFR_RNDD);
     154    if (mpfr_cmp_ui_2exp(x, 1, -1))
     155      {
     156        printf ("mpfr_tan(0.5, MPFR_RNDD) failed\n"
     157                "expected 0.5, got ");
     158        mpfr_dump (x);
     159        exit (1);
     160      }
     161  
     162    /* check that tan(3*Pi/4) ~ -1 */
     163    for (i=0; i<10; i++)
     164      {
     165        mpfr_set_prec (x, prec[i]);
     166        mpfr_const_pi (x, MPFR_RNDN);
     167        mpfr_mul_ui (x, x, 3, MPFR_RNDN);
     168        mpfr_div_ui (x, x, 4, MPFR_RNDN);
     169        mpfr_tan (x, x, MPFR_RNDN);
     170        if (mpfr_cmp_si (x, -1))
     171          {
     172            printf ("tan(3*Pi/4) fails for prec=%u\n", prec[i]);
     173            exit (1);
     174          }
     175      }
     176  
     177    /* check that tan(7*Pi/4) ~ -1 */
     178    for (i=0; i<10; i++)
     179      {
     180        mpfr_set_prec (x, prec2[i]);
     181        mpfr_const_pi (x, MPFR_RNDN);
     182        mpfr_mul_ui (x, x, 7, MPFR_RNDN);
     183        mpfr_div_ui (x, x, 4, MPFR_RNDN);
     184        mpfr_tan (x, x, MPFR_RNDN);
     185        if (mpfr_cmp_si (x, -1))
     186          {
     187            printf ("tan(3*Pi/4) fails for prec=%u\n", prec2[i]);
     188            exit (1);
     189          }
     190      }
     191  
     192    mpfr_clear (x);
     193  
     194    test_generic (MPFR_PREC_MIN, 100, 10);
     195  
     196    data_check ("data/tan", mpfr_tan, "mpfr_tan");
     197    bad_cases (mpfr_tan, mpfr_atan, "mpfr_tan", 256, -256, 255, 4, 128, 800, 40);
     198  
     199    tests_end_mpfr ();
     200    return 0;
     201  }