(root)/
mpfr-4.2.1/
tests/
ttanu.c
       1  /* Test file for mpfr_tanu.
       2  
       3  Copyright 2020-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  static void
      26  test_singular (void)
      27  {
      28    mpfr_t x, y;
      29    int inexact;
      30  
      31    mpfr_init (x);
      32    mpfr_init (y);
      33  
      34    /* check u = 0 */
      35    mpfr_set_ui (x, 17, MPFR_RNDN);
      36    inexact = mpfr_tanu (y, x, 0, MPFR_RNDN);
      37    MPFR_ASSERTN(mpfr_nan_p (y));
      38  
      39    /* check x = NaN */
      40    mpfr_set_nan (x);
      41    inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
      42    MPFR_ASSERTN(mpfr_nan_p (y));
      43  
      44    /* check x = +Inf */
      45    mpfr_set_inf (x, 1);
      46    inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
      47    MPFR_ASSERTN(mpfr_nan_p (y));
      48  
      49    /* check x = -Inf */
      50    mpfr_set_inf (x, -1);
      51    inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
      52    MPFR_ASSERTN(mpfr_nan_p (y));
      53  
      54    /* check x = +0 */
      55    mpfr_set_zero (x, 1);
      56    inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
      57    MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
      58    MPFR_ASSERTN(inexact == 0);
      59  
      60    /* check x = -0 */
      61    mpfr_set_zero (x, -1);
      62    inexact = mpfr_tanu (y, x, 1, MPFR_RNDN);
      63    MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
      64    MPFR_ASSERTN(inexact == 0);
      65  
      66    mpfr_clear (x);
      67    mpfr_clear (y);
      68  }
      69  
      70  static void
      71  test_exact (void)
      72  {
      73    mpfr_t x, y;
      74    int inexact, n;
      75  
      76    mpfr_init2 (x, 6);
      77    mpfr_init2 (y, 6);
      78  
      79    /* check n + 0.5 for n integer */
      80    for (n = 0; n < 10; n++)
      81      {
      82        /* check 2n+0.5 for n>=0: +Inf and divide by 0 exception */
      83        mpfr_set_ui (x, 4 * n + 1, MPFR_RNDN);
      84        mpfr_clear_divby0 ();
      85        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
      86        MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
      87        MPFR_ASSERTN(inexact == 0);
      88        MPFR_ASSERTN(mpfr_divby0_p ());
      89  
      90        /* check 2n+1 for n>=0: -0 */
      91        mpfr_set_ui (x, 4 * n + 2, MPFR_RNDN);
      92        mpfr_clear_divby0 ();
      93        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
      94        MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
      95        MPFR_ASSERTN(inexact == 0);
      96        MPFR_ASSERTN(!mpfr_divby0_p ());
      97  
      98        /* check 2n+1.5 for n>=0: -Inf and divide by 0 exception */
      99        mpfr_set_ui (x, 4 * n + 3, MPFR_RNDN);
     100        mpfr_clear_divby0 ();
     101        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     102        MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
     103        MPFR_ASSERTN(inexact == 0);
     104        MPFR_ASSERTN(mpfr_divby0_p ());
     105  
     106        /* check 2n+2 for n>=0: +0 */
     107        mpfr_set_ui (x, 4 * n + 4, MPFR_RNDN);
     108        mpfr_clear_divby0 ();
     109        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     110        MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
     111        MPFR_ASSERTN(inexact == 0);
     112        MPFR_ASSERTN(!mpfr_divby0_p ());
     113  
     114        /* check -2n-0.5 for n>=0: -Inf and divide by 0 exception */
     115        mpfr_set_si (x, -4 * n - 1, MPFR_RNDN);
     116        mpfr_clear_divby0 ();
     117        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     118        MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
     119        MPFR_ASSERTN(inexact == 0);
     120        MPFR_ASSERTN(mpfr_divby0_p ());
     121  
     122        /* check -2n-1 for n>=0: +0 */
     123        mpfr_set_si (x, -4 * n - 2, MPFR_RNDN);
     124        mpfr_clear_divby0 ();
     125        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     126        MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0);
     127        MPFR_ASSERTN(inexact == 0);
     128        MPFR_ASSERTN(!mpfr_divby0_p ());
     129  
     130        /* check -2n-1.5 for n>=0: +Inf and divide by 0 exception */
     131        mpfr_set_si (x, -4 * n - 3, MPFR_RNDN);
     132        mpfr_clear_divby0 ();
     133        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     134        MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
     135        MPFR_ASSERTN(inexact == 0);
     136        MPFR_ASSERTN(mpfr_divby0_p ());
     137  
     138        /* check -2n-2 for n>=0: -0 */
     139        mpfr_set_si (x, -4 * n - 4, MPFR_RNDN);
     140        mpfr_clear_divby0 ();
     141        inexact = mpfr_tanu (y, x, 4, MPFR_RNDN);
     142        MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) != 0);
     143        MPFR_ASSERTN(inexact == 0);
     144        MPFR_ASSERTN(!mpfr_divby0_p ());
     145      }
     146  
     147    /* check 2*pi*x/u = pi/4 thus x/u = 1/8, for example x=1 and u=8 */
     148    mpfr_set_ui (x, 1, MPFR_RNDN);
     149    inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
     150    MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0 && inexact == 0);
     151  
     152    /* check 2*pi*x/u = 3*pi/4 thus x/u = 3/8, for example x=3 and u=8 */
     153    mpfr_set_ui (x, 3, MPFR_RNDN);
     154    inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
     155    MPFR_ASSERTN(mpfr_cmp_si (y, -1) == 0 && inexact == 0);
     156  
     157    /* check 2*pi*x/u = 5*pi/4 thus x/u = 5/8, for example x=5 and u=8 */
     158    mpfr_set_ui (x, 5, MPFR_RNDN);
     159    inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
     160    MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0 && inexact == 0);
     161  
     162    /* check 2*pi*x/u = 7*pi/4 thus x/u = 7/8, for example x=7 and u=8 */
     163    mpfr_set_ui (x, 7, MPFR_RNDN);
     164    inexact = mpfr_tanu (y, x, 8, MPFR_RNDN);
     165    MPFR_ASSERTN(mpfr_cmp_si (y, -1) == 0 && inexact == 0);
     166  
     167    mpfr_clear (x);
     168    mpfr_clear (y);
     169  }
     170  
     171  static void
     172  test_regular (void)
     173  {
     174    mpfr_t x, y, z;
     175    int inexact;
     176  
     177    mpfr_init2 (x, 53);
     178    mpfr_init2 (y, 53);
     179    mpfr_init2 (z, 53);
     180  
     181    mpfr_set_ui (x, 17, MPFR_RNDN);
     182    inexact = mpfr_tanu (y, x, 42, MPFR_RNDN);
     183    /* y should be tan(2*17*pi/42) rounded to nearest */
     184    mpfr_set_str (z, "-0xa.e89b03074638p-4", 16, MPFR_RNDN);
     185    MPFR_ASSERTN(mpfr_equal_p (y, z));
     186    MPFR_ASSERTN(inexact > 0);
     187  
     188    mpfr_clear (x);
     189    mpfr_clear (y);
     190    mpfr_clear (z);
     191  }
     192  
     193  /* Check argument reduction with large hard-coded inputs. The following
     194     values were generated with gen_random(tan,10,53,100,20), where the
     195     Sage code for gen_random is given in the tcosu.c file. */
     196  static void
     197  test_large (void)
     198  {
     199    static struct {
     200      const char *x;
     201      unsigned long u;
     202      const char *y;
     203    } t[] = {
     204      { "-0x1.8f7cb49edc03p+16", 28, "0x4.c869fd8050554p-4" },
     205      { "-0xe.8ede30716292p+16", 17, "-0x2.c83df69d8fdecp+4" },
     206      { "-0x8.f14a73a7b4a3p+16", 4, "-0xd.be24a6d0fde98p-4" },
     207      { "0xe.f82c4537b473p+16", 93, "-0x5.d0d95fdc8ffbcp+0" },
     208      { "0x8.4148f00c8418p+16", 50, "0x1.e4e4aa652b2a4p-4" },
     209      { "-0x6.e8b69db10e63p+16", 27, "-0x2.4f32f1977b7b2p-4" },
     210      { "-0xe.a3ebf225ea2fp+16", 18, "0x6.5f7637f74517p+0" },
     211      { "-0x5.580eb29168d8p+16", 92, "0x8.96418eed84e8p+0" },
     212      { "0x8.13c5a1b43231p+16", 19, "0xb.2718b861b29fp-8" },
     213      { "0x4.eb4e546e042dp+16", 64, "0x6.0b3ba821e4ep+0" }
     214    };
     215    int i;
     216    mpfr_t x, y, z;
     217  
     218    mpfr_inits2 (53, x, y, z, (mpfr_ptr) 0);
     219    for (i = 0; i < numberof (t); i++)
     220      {
     221        mpfr_set_str (x, t[i].x, 0, MPFR_RNDN);
     222        mpfr_set_str (y, t[i].y, 0, MPFR_RNDN);
     223        mpfr_tanu (z, x, t[i].u, MPFR_RNDN);
     224        MPFR_ASSERTN (mpfr_equal_p (y, z));
     225      }
     226    mpfr_clears (x, y, z, (mpfr_ptr) 0);
     227  }
     228  
     229  #define TEST_FUNCTION mpfr_tanu
     230  #define ULONG_ARG2
     231  #include "tgeneric.c"
     232  
     233  static int
     234  mpfr_tan2pi (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t r)
     235  {
     236    return mpfr_tanu (y, x, 1, r);
     237  }
     238  
     239  int
     240  main (void)
     241  {
     242    tests_start_mpfr ();
     243  
     244    test_singular ();
     245    test_exact ();
     246    test_regular ();
     247    test_large ();
     248  
     249    test_generic (MPFR_PREC_MIN, 100, 1000);
     250  
     251    data_check ("data/tan2pi", mpfr_tan2pi, "mpfr_tan2pi");
     252  
     253    tests_end_mpfr ();
     254    return 0;
     255  }