1275970Scy/* Test file for mpfr_asinu. 2275970Scy 3275970ScyCopyright 2021-2023 Free Software Foundation, Inc. 4275970ScyContributed by the AriC and Caramba projects, INRIA. 5275970Scy 6275970ScyThis file is part of the GNU MPFR Library. 7275970Scy 8275970ScyThe GNU MPFR Library is free software; you can redistribute it and/or modify 9275970Scyit under the terms of the GNU Lesser General Public License as published by 10275970Scythe Free Software Foundation; either version 3 of the License, or (at your 11275970Scyoption) any later version. 12275970Scy 13275970ScyThe GNU MPFR Library is distributed in the hope that it will be useful, but 14275970ScyWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15275970Scyor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16275970ScyLicense for more details. 17275970Scy 18275970ScyYou should have received a copy of the GNU Lesser General Public License 19275970Scyalong with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20275970Scyhttps://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21275970Scy51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22275970Scy 23275970Scy#include "mpfr-test.h" 24275970Scy 25275970Scy#define TEST_FUNCTION mpfr_asinu 26275970Scy#define ULONG_ARG2 27275970Scy#include "tgeneric.c" 28275970Scy 29275970Scystatic void 30275970Scycheck_underflow (void) 31275970Scy{ 32275970Scy mpfr_t x, y; 33275970Scy mpfr_exp_t emin = mpfr_get_emin (); 34275970Scy 35275970Scy set_emin (mpfr_get_emin_min ()); 36275970Scy 37275970Scy mpfr_init2 (x, MPFR_PREC_MIN); 38275970Scy mpfr_init2 (y, MPFR_PREC_MIN); 39330567Sgordon mpfr_set_ui_2exp (x, 1, mpfr_get_emin_min () - 1, MPFR_RNDN); 40275970Scy /* asinu(x,1) = asin(x)/(2*pi) will underflow */ 41275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 42275970Scy MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0); 43275970Scy mpfr_asinu (y, x, 1, MPFR_RNDZ); 44275970Scy MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0); 45275970Scy mpfr_asinu (y, x, 1, MPFR_RNDU); 46275970Scy MPFR_ASSERTN(mpfr_cmp_ui_2exp (y, 1, mpfr_get_emin_min () - 1) == 0); 47275970Scy mpfr_clear (x); 48275970Scy mpfr_clear (y); 49275970Scy 50275970Scy set_emin (emin); 51275970Scy} 52275970Scy 53275970Scyint 54275970Scymain (void) 55275970Scy{ 56275970Scy mpfr_t x, y; 57275970Scy int r, inex; 58275970Scy unsigned long u; 59275970Scy 60275970Scy tests_start_mpfr (); 61275970Scy 62275970Scy check_underflow (); 63275970Scy 64275970Scy mpfr_init (x); 65275970Scy mpfr_init (y); 66275970Scy 67275970Scy /* check singular cases */ 68275970Scy MPFR_SET_NAN(x); 69275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 70275970Scy if (mpfr_nan_p (y) == 0) 71275970Scy { 72275970Scy printf ("Error: asinu (NaN, 1) != NaN\n"); 73275970Scy exit (1); 74275970Scy } 75275970Scy 76275970Scy mpfr_set_inf (x, 1); 77275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 78275970Scy if (mpfr_nan_p (y) == 0) 79275970Scy { 80275970Scy printf ("Error: asinu (+Inf, 1) != NaN\n"); 81275970Scy exit (1); 82275970Scy } 83275970Scy 84275970Scy mpfr_set_inf (x, -1); 85275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 86275970Scy if (mpfr_nan_p (y) == 0) 87275970Scy { 88275970Scy printf ("Error: asinu (-Inf, 1) != NaN\n"); 89275970Scy exit (1); 90275970Scy } 91275970Scy 92275970Scy /* asinu (+0,u) = +0 */ 93275970Scy mpfr_set_ui (x, 0, MPFR_RNDN); 94275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 95275970Scy if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) 96275970Scy { 97275970Scy printf ("Error: asinu(+0,1) != +0\n"); 98275970Scy exit (1); 99275970Scy } 100275970Scy 101275970Scy /* asinu (-0,u) = -0 */ 102275970Scy mpfr_set_ui (x, 0, MPFR_RNDN); 103275970Scy mpfr_neg (x, x, MPFR_RNDN); 104275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 105275970Scy if (MPFR_NOTZERO (y) || MPFR_IS_POS (y)) 106275970Scy { 107275970Scy printf ("Error: asinu(-0,1) != -0\n"); 108275970Scy exit (1); 109275970Scy } 110275970Scy 111275970Scy /* tests for |x| > 1 */ 112275970Scy mpfr_set_ui (x, 2, MPFR_RNDN); 113275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 114275970Scy if (mpfr_nan_p (y) == 0) 115275970Scy { 116275970Scy printf ("Error: asinu (2, 1) != NaN\n"); 117275970Scy exit (1); 118275970Scy } 119275970Scy 120275970Scy mpfr_set_si (x, -2, MPFR_RNDN); 121275970Scy mpfr_asinu (y, x, 1, MPFR_RNDN); 122275970Scy if (mpfr_nan_p (y) == 0) 123275970Scy { 124275970Scy printf ("Error: asinu (-2, 1) != NaN\n"); 125275970Scy exit (1); 126275970Scy } 127275970Scy 128275970Scy mpfr_set_ui (x, 2, MPFR_RNDN); 129275970Scy mpfr_asinu (y, x, 0, MPFR_RNDN); 130275970Scy if (mpfr_nan_p (y) == 0) 131275970Scy { 132275970Scy printf ("Error: asinu (2, 0) != NaN\n"); 133275970Scy exit (1); 134275970Scy } 135275970Scy 136275970Scy mpfr_set_si (x, -2, MPFR_RNDN); 137275970Scy mpfr_asinu (y, x, 0, MPFR_RNDN); 138275970Scy if (mpfr_nan_p (y) == 0) 139275970Scy { 140275970Scy printf ("Error: asinu (-2, 0) != NaN\n"); 141275970Scy exit (1); 142275970Scy } 143275970Scy 144275970Scy /* asinu (1,u) = u/4 */ 145275970Scy RND_LOOP (r) 146275970Scy { 147275970Scy mpfr_set_si (x, 1, MPFR_RNDN); /* exact */ 148275970Scy mpfr_asinu (y, x, 17, (mpfr_rnd_t) r); 149275970Scy mpfr_set_ui_2exp (x, 17, -2, (mpfr_rnd_t) r); 150275970Scy if (!mpfr_equal_p (x, y)) 151275970Scy { 152275970Scy printf ("Error: asinu(1,17) != 17/4 for rnd=%s\n", 153275970Scy mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 154275970Scy exit (1); 155330567Sgordon } 156275970Scy } 157275970Scy 158275970Scy /* asinu (-1,u) = -u/4 */ 159275970Scy RND_LOOP (r) 160275970Scy { 161275970Scy mpfr_set_si (x, -1, MPFR_RNDN); /* exact */ 162275970Scy mpfr_asinu (y, x, 17, (mpfr_rnd_t) r); 163275970Scy mpfr_set_si_2exp (x, -17, -2, (mpfr_rnd_t) r); 164275970Scy if (!mpfr_equal_p (x, y)) 165275970Scy { 166275970Scy printf ("Error: asinu(-1,17) != -17/4 for rnd=%s\n", 167275970Scy mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 168275970Scy exit (1); 169275970Scy } 170275970Scy } 171275970Scy 172275970Scy /* asinu (1/2,u) = u/12 */ 173275970Scy for (u = 1; u < 100; u++) 174275970Scy RND_LOOP (r) 175275970Scy { 176275970Scy mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN); /* exact */ 177275970Scy mpfr_asinu (y, x, u, (mpfr_rnd_t) r); 178275970Scy inex = mpfr_set_ui (x, u, MPFR_RNDN); 179275970Scy MPFR_ASSERTN(inex == 0); 180275970Scy inex = mpfr_div_ui (x, x, 12, (mpfr_rnd_t) r); 181275970Scy if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y)) 182275970Scy { 183275970Scy printf ("Error: asinu(1/2,u) != u/12 for u=%lu and rnd=%s\n", 184275970Scy u, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 185275970Scy printf ("got: "); mpfr_dump (y); 186275970Scy exit (1); 187275970Scy } 188275970Scy } 189275970Scy 190275970Scy /* asinu (-1/2,u) = -u/12 */ 191275970Scy for (u = 1; u < 100; u++) 192275970Scy RND_LOOP (r) 193275970Scy { 194275970Scy mpfr_set_si_2exp (x, -1, -1, MPFR_RNDN); /* exact */ 195275970Scy mpfr_asinu (y, x, u, (mpfr_rnd_t) r); 196275970Scy inex = mpfr_set_ui (x, u, MPFR_RNDN); 197275970Scy MPFR_ASSERTN(inex == 0); 198275970Scy inex = mpfr_div_si (x, x, -12, (mpfr_rnd_t) r); 199275970Scy if ((r != MPFR_RNDF || inex == 0) && !mpfr_equal_p (x, y)) 200275970Scy { 201275970Scy printf ("Error: asinu(-1/2,u) != -u/12 for u=%lu and rnd=%s\n", 202275970Scy u, mpfr_print_rnd_mode ((mpfr_rnd_t) r)); 203275970Scy printf ("expected: "); mpfr_dump (x); 204275970Scy printf ("got: "); mpfr_dump (y); 205275970Scy exit (1); 206275970Scy } 207275970Scy } 208275970Scy 209275970Scy test_generic (MPFR_PREC_MIN, 100, 100); 210275970Scy 211275970Scy mpfr_clear (x); 212275970Scy mpfr_clear (y); 213275970Scy 214275970Scy tests_end_mpfr (); 215275970Scy return 0; 216275970Scy} 217275970Scy