(root)/
mpfr-4.2.1/
tests/
tasin.c
       1  /* Test file for mpfr_asin.
       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  #define TEST_FUNCTION mpfr_asin
      26  #define TEST_RANDOM_EMAX 7
      27  #include "tgeneric.c"
      28  
      29  static void
      30  special (void)
      31  {
      32    mpfr_t x, y;
      33    int r;
      34  
      35    mpfr_init (x);
      36    mpfr_init (y);
      37  
      38    /* asin(NaN) = NaN */
      39    mpfr_set_nan (x);
      40    mpfr_asin (y, x, MPFR_RNDN);
      41    if (!mpfr_nan_p (y))
      42      {
      43        printf ("Error: mpfr_asin (NaN) <> NaN\n");
      44        exit (1);
      45      }
      46  
      47    /* asin(+/-Inf) = NaN */
      48    mpfr_set_inf (x, 1);
      49    mpfr_asin (y, x, MPFR_RNDN);
      50    if (!mpfr_nan_p (y))
      51      {
      52        printf ("Error: mpfr_asin (+Inf) <> NaN\n");
      53        exit (1);
      54      }
      55    mpfr_set_inf (x, -1);
      56    mpfr_asin (y, x, MPFR_RNDN);
      57    if (!mpfr_nan_p (y))
      58      {
      59        printf ("Error: mpfr_asin (-Inf) <> NaN\n");
      60        exit (1);
      61      }
      62  
      63    /* asin(+/-2) = NaN */
      64    mpfr_set_ui (x, 2, MPFR_RNDN);
      65    mpfr_asin (y, x, MPFR_RNDN);
      66    if (!mpfr_nan_p (y))
      67      {
      68        printf ("Error: mpfr_asin (+2) <> NaN\n");
      69        exit (1);
      70      }
      71    mpfr_set_si (x, -2, MPFR_RNDN);
      72    mpfr_asin (y, x, MPFR_RNDN);
      73    if (!mpfr_nan_p (y))
      74      {
      75        printf ("Error: mpfr_asin (-2) <> NaN\n");
      76        exit (1);
      77      }
      78  
      79    /* asin(+/-0) = +/-0 */
      80    mpfr_set_ui (x, 0, MPFR_RNDN);
      81    mpfr_asin (y, x, MPFR_RNDN);
      82    if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y))
      83      {
      84        printf ("Error: mpfr_asin (+0) <> +0\n");
      85        exit (1);
      86      }
      87    mpfr_neg (x, x, MPFR_RNDN);
      88    mpfr_asin (y, x, MPFR_RNDN);
      89    if (MPFR_NOTZERO (y) || MPFR_IS_POS (y))
      90      {
      91        printf ("Error: mpfr_asin (-0) <> -0\n");
      92        exit (1);
      93      }
      94  
      95    /* asin(1) = Pi/2 */
      96    RND_LOOP (r)
      97      {
      98        mpfr_set_ui (x, 1, MPFR_RNDN); /* exact */
      99        mpfr_asin (y, x, (mpfr_rnd_t) r);
     100        mpfr_const_pi (x, (mpfr_rnd_t) r);
     101        mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* exact */
     102        if (mpfr_cmp (x, y))
     103          {
     104            printf ("Error: asin(1) != Pi/2 for rnd=%s\n",
     105                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
     106            exit (1);
     107          }
     108      }
     109  
     110    /* asin(-1) = -Pi/2 */
     111    RND_LOOP (r)
     112      {
     113        mpfr_set_si (x, -1, MPFR_RNDN); /* exact */
     114        mpfr_asin (y, x, (mpfr_rnd_t) r);
     115        mpfr_const_pi (x, MPFR_INVERT_RND((mpfr_rnd_t) r));
     116        mpfr_neg (x, x, MPFR_RNDN); /* exact */
     117        mpfr_div_2ui (x, x, 1, MPFR_RNDN); /* exact */
     118        if (mpfr_cmp (x, y))
     119          {
     120            printf ("Error: asin(-1) != -Pi/2 for rnd=%s\n",
     121                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
     122            exit (1);
     123          }
     124      }
     125  
     126    mpfr_set_prec (x, 32);
     127    mpfr_set_prec (y, 32);
     128  
     129    mpfr_set_str_binary (x, "0.1101110111111111001011101000101");
     130    mpfr_asin (x, x, MPFR_RNDN);
     131    mpfr_set_str_binary (y, "1.00001100101011000001111100111");
     132    if (mpfr_cmp (x, y))
     133      {
     134        printf ("Error: mpfr_asin (1)\n");
     135        exit (1);
     136      }
     137  
     138    mpfr_set_str_binary (x, "-0.01110111000011101010111100000101");
     139    mpfr_asin (x, x, MPFR_RNDN);
     140    mpfr_set_str_binary (y, "-0.0111101111010100011111110101");
     141    if (mpfr_cmp (x, y))
     142      {
     143        printf ("Error: mpfr_asin (2)\n");
     144        mpfr_dump (x);
     145        mpfr_dump (y);
     146        exit (1);
     147      }
     148  
     149    mpfr_set_prec (x, 9);
     150    mpfr_set_prec (y, 19);
     151    mpfr_set_str_binary (x, "0.110000000E-6");
     152    mpfr_asin (y, x, MPFR_RNDD);
     153    mpfr_set_prec (x, 19);
     154    mpfr_set_str_binary (x, "0.1100000000000001001E-6");
     155    if (mpfr_cmp (x, y))
     156      {
     157        printf ("Error: mpfr_asin (3)\n");
     158        mpfr_dump (x);
     159        mpfr_dump (y);
     160        exit (1);
     161      }
     162  
     163    mpfr_clear (x);
     164    mpfr_clear (y);
     165  }
     166  
     167  static void
     168  special_overflow (void)
     169  {
     170    mpfr_t x, y;
     171    mpfr_exp_t emin, emax;
     172  
     173    emin = mpfr_get_emin ();
     174    emax = mpfr_get_emax ();
     175  
     176    set_emin (-125);
     177    set_emax (128);
     178    mpfr_init2 (x, 24);
     179    mpfr_init2 (y, 48);
     180    mpfr_set_str_binary (x, "0.101100100000000000110100E0");
     181    mpfr_asin (y, x, MPFR_RNDN);
     182    if (mpfr_cmp_str (y, "0.110001001101001111110000010110001000111011001000E0",
     183                      2, MPFR_RNDN))
     184      {
     185        printf("Special Overflow error.\n");
     186        mpfr_dump (y);
     187        exit (1);
     188      }
     189    mpfr_clear (y);
     190    mpfr_clear (x);
     191    set_emin (emin);
     192    set_emax (emax);
     193  }
     194  
     195  /* bug reported by Kevin Rauch on 15 December 2007 */
     196  static void
     197  test20071215 (void)
     198  {
     199    mpfr_t x, y;
     200  
     201    mpfr_init (x);
     202    mpfr_init (y);
     203  
     204    mpfr_set_ui (x, 0, MPFR_RNDN);
     205    mpfr_neg (x, x, MPFR_RNDN);
     206    mpfr_set_ui (y, 1, MPFR_RNDN);
     207    mpfr_asin (y, x, MPFR_RNDN);
     208    MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_NEG(y));
     209  
     210    mpfr_set_ui (x, 0, MPFR_RNDN);
     211    mpfr_set_si (y, -1, MPFR_RNDN);
     212    mpfr_asin (y, x, MPFR_RNDN);
     213    MPFR_ASSERTN(mpfr_zero_p (y) && MPFR_IS_POS(y));
     214  
     215    mpfr_clear (x);
     216    mpfr_clear (y);
     217  }
     218  
     219  static void
     220  reduced_expo_range (void)
     221  {
     222    mpfr_exp_t emin, emax;
     223    mpfr_t x, y, ex_y;
     224    int inex, ex_inex;
     225    unsigned int flags, ex_flags;
     226  
     227    emin = mpfr_get_emin ();
     228    emax = mpfr_get_emax ();
     229  
     230    mpfr_inits2 (4, x, y, ex_y, (mpfr_ptr) 0);
     231    mpfr_set_str (x, "-0.1e1", 2, MPFR_RNDN);
     232  
     233    set_emin (1);
     234    set_emax (1);
     235    mpfr_clear_flags ();
     236    inex = mpfr_asin (y, x, MPFR_RNDA);
     237    flags = __gmpfr_flags;
     238    set_emin (emin);
     239    set_emax (emax);
     240  
     241    mpfr_set_str (ex_y, "-0.1101e1", 2, MPFR_RNDN);
     242    ex_inex = -1;
     243    ex_flags = MPFR_FLAGS_INEXACT;
     244  
     245    if (VSIGN (inex) != ex_inex || flags != ex_flags ||
     246        ! mpfr_equal_p (y, ex_y))
     247      {
     248        printf ("Error in reduced_expo_range\non x = ");
     249        mpfr_dump (x);
     250        printf ("Expected y = ");
     251        mpfr_out_str (stdout, 2, 0, ex_y, MPFR_RNDN);
     252        printf ("\n         inex = %d, flags = %u\n", ex_inex, ex_flags);
     253        printf ("Got      y = ");
     254        mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
     255        printf ("\n         inex = %d, flags = %u\n", VSIGN (inex), flags);
     256        exit (1);
     257      }
     258  
     259    mpfr_clears (x, y, ex_y, (mpfr_ptr) 0);
     260  }
     261  
     262  int
     263  main (void)
     264  {
     265    tests_start_mpfr ();
     266  
     267    special ();
     268    special_overflow ();
     269    reduced_expo_range ();
     270  
     271    test_generic (MPFR_PREC_MIN, 100, 15);
     272  
     273    tests_end_mpfr ();
     274  
     275    data_check ("data/asin", mpfr_asin, "mpfr_asin");
     276    bad_cases (mpfr_asin, mpfr_sin, "mpfr_asin", 256, -40, 1, 4, 128, 800, 30);
     277  
     278    test20071215 ();
     279  
     280    tests_end_mpfr ();
     281    return 0;
     282  }