1 /* Test file for mpfr_asin. 2 3 Copyright 2001-2018 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 http://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 for (r = 0; r < MPFR_RND_MAX; 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_2exp (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 for (r = 0; r < MPFR_RND_MAX; 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_2exp (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 mpfr_set_emin (1); 234 mpfr_set_emax (1); 235 mpfr_clear_flags (); 236 inex = mpfr_asin (y, x, MPFR_RNDA); 237 flags = __gmpfr_flags; 238 mpfr_set_emin (emin); 239 mpfr_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 } 283