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