1/* Test file for mpfr_asin. 2 3Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4Contributed by the Arenaire and Cacao projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 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 32static void 33special (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 170static void 171special_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 */ 199static void 200test20071215 (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 222static void 223reduced_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 265int 266main (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