1 /* Test file for mpfr_hypot. 2 3 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramel 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 <limits.h> 25 #include <stdlib.h> 26 27 #include "mpfr-test.h" 28 29 /* Non-zero when extended exponent range */ 30 static int ext = 0; 31 32 static void 33 special (void) 34 { 35 mpfr_t x, y, z; 36 37 mpfr_init (x); 38 mpfr_init (y); 39 mpfr_init (z); 40 41 mpfr_set_nan (x); 42 mpfr_hypot (z, x, y, MPFR_RNDN); 43 MPFR_ASSERTN(mpfr_nan_p (z)); 44 45 mpfr_set_inf (x, 1); 46 mpfr_set_inf (y, -1); 47 mpfr_hypot (z, x, y, MPFR_RNDN); 48 MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 49 50 mpfr_set_inf (x, -1); 51 mpfr_set_nan (y); 52 mpfr_hypot (z, x, y, MPFR_RNDN); 53 MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 54 55 mpfr_set_nan (x); 56 mpfr_set_inf (y, -1); 57 mpfr_hypot (z, x, y, MPFR_RNDN); 58 MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 59 60 mpfr_clear (x); 61 mpfr_clear (y); 62 mpfr_clear (z); 63 } 64 65 static void 66 test_large (void) 67 { 68 mpfr_t x, y, z, t; 69 70 mpfr_init (x); 71 mpfr_init (y); 72 mpfr_init (z); 73 mpfr_init (t); 74 75 mpfr_set_ui (x, 21, MPFR_RNDN); 76 mpfr_set_ui (y, 28, MPFR_RNDN); 77 mpfr_set_ui (z, 35, MPFR_RNDN); 78 79 mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 80 mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 81 mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 82 83 mpfr_hypot (t, x, y, MPFR_RNDN); 84 if (mpfr_cmp (z, t)) 85 { 86 printf ("Error in test_large: got\n"); 87 mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 88 printf ("\ninstead of\n"); 89 mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 90 printf ("\n"); 91 exit (1); 92 } 93 94 mpfr_set_prec (x, 53); 95 mpfr_set_prec (t, 53); 96 mpfr_set_prec (y, 53); 97 mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021"); 98 mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021"); 99 mpfr_hypot (t, x, y, MPFR_RNDN); 100 mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020"); 101 if (mpfr_cmp (z, t)) 102 { 103 printf ("Error in test_large: got\n"); 104 mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 105 printf ("\ninstead of\n"); 106 mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 107 printf ("\n"); 108 exit (1); 109 } 110 111 mpfr_set_prec (x, 240); 112 mpfr_set_prec (y, 22); 113 mpfr_set_prec (z, 2); 114 mpfr_set_prec (t, 2); 115 mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7"); 116 mpfr_set_str_binary (y, "0.1111000010000011000111E-10"); 117 mpfr_hypot (t, x, y, MPFR_RNDN); 118 mpfr_set_str_binary (z, "0.11E-7"); 119 if (mpfr_cmp (z, t)) 120 { 121 printf ("Error in test_large: got\n"); 122 mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 123 printf ("\ninstead of\n"); 124 mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 125 printf ("\n"); 126 exit (1); 127 } 128 129 mpfr_clear (x); 130 mpfr_clear (y); 131 mpfr_clear (z); 132 mpfr_clear (t); 133 } 134 135 static void 136 test_small (void) 137 { 138 mpfr_t x, y, z1, z2; 139 int inex1, inex2; 140 unsigned int flags; 141 142 /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */ 143 mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0); 144 mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN); 145 mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN); 146 mpfr_set_ui (z1, 2, MPFR_RNDN); 147 inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN); 148 inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN); 149 MPFR_ASSERTN (inex2 == 0); 150 mpfr_clear_flags (); 151 inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN); 152 flags = __gmpfr_flags; 153 if (mpfr_cmp (z1, z2) != 0) 154 { 155 printf ("Error in test_small%s\nExpected ", 156 ext ? ", extended exponent range" : ""); 157 mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN); 158 printf ("\nGot "); 159 mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN); 160 printf ("\n"); 161 exit (1); 162 } 163 if (! SAME_SIGN (inex1, inex2)) 164 { 165 printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n", 166 ext ? ", extended exponent range" : "", inex1, inex2); 167 exit (1); 168 } 169 if (flags != MPFR_FLAGS_INEXACT) 170 { 171 printf ("Bad flags in test_small%s\nExpected %u, got %u\n", 172 ext ? ", extended exponent range" : "", 173 (unsigned int) MPFR_FLAGS_INEXACT, flags); 174 exit (1); 175 } 176 mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); 177 } 178 179 static void 180 test_large_small (void) 181 { 182 mpfr_t x, y, z; 183 int inexact, inex2, r; 184 185 mpfr_init2 (x, 3); 186 mpfr_init2 (y, 2); 187 mpfr_init2 (z, 2); 188 189 mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN); 190 mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN); 191 inexact = mpfr_hypot (z, x, y, MPFR_RNDN); 192 if (inexact >= 0 || mpfr_cmp (x, z)) 193 { 194 printf ("Error 1 in test_large_small%s\n", 195 ext ? ", extended exponent range" : ""); 196 exit (1); 197 } 198 199 mpfr_mul_ui (x, x, 5, MPFR_RNDN); 200 inexact = mpfr_hypot (z, x, y, MPFR_RNDN); 201 if (mpfr_cmp (x, z) >= 0) 202 { 203 printf ("Error 2 in test_large_small%s\n", 204 ext ? ", extended exponent range" : ""); 205 printf ("x = "); 206 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 207 printf ("\n"); 208 printf ("y = "); 209 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 210 printf ("\n"); 211 printf ("z = "); 212 mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 213 printf (" (in precision 2) instead of\n "); 214 mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU); 215 printf ("\n"); 216 exit (1); 217 } 218 219 RND_LOOP(r) 220 { 221 mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN); 222 mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN); 223 inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r); 224 inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r); 225 if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2)) 226 { 227 printf ("Error 3 in test_large_small, %s%s\n", 228 mpfr_print_rnd_mode ((mpfr_rnd_t) r), 229 ext ? ", extended exponent range" : ""); 230 printf ("Expected "); 231 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 232 printf (", inex = %d\n", inex2); 233 printf ("Got "); 234 mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 235 printf (", inex = %d\n", inexact); 236 exit (1); 237 } 238 } 239 240 mpfr_clear (x); 241 mpfr_clear (y); 242 mpfr_clear (z); 243 } 244 245 static void 246 check_overflow (void) 247 { 248 mpfr_t x, y; 249 int inex, r; 250 251 mpfr_inits2 (8, x, y, (mpfr_ptr) 0); 252 mpfr_set_ui (x, 1, MPFR_RNDN); 253 mpfr_setmax (x, mpfr_get_emax ()); 254 255 RND_LOOP(r) 256 { 257 mpfr_clear_overflow (); 258 inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r); 259 if (!mpfr_overflow_p ()) 260 { 261 printf ("No overflow in check_overflow for %s%s\n", 262 mpfr_print_rnd_mode ((mpfr_rnd_t) r), 263 ext ? ", extended exponent range" : ""); 264 exit (1); 265 } 266 MPFR_ASSERTN (MPFR_IS_POS (y)); 267 if (r == MPFR_RNDZ || r == MPFR_RNDD) 268 { 269 MPFR_ASSERTN (inex < 0); 270 MPFR_ASSERTN (!mpfr_inf_p (y)); 271 mpfr_nexttoinf (y); 272 } 273 else 274 { 275 MPFR_ASSERTN (inex > 0); 276 } 277 MPFR_ASSERTN (mpfr_inf_p (y)); 278 } 279 280 mpfr_clears (x, y, (mpfr_ptr) 0); 281 } 282 283 #define TWO_ARGS 284 #define TEST_FUNCTION mpfr_hypot 285 #include "tgeneric.c" 286 287 static void 288 alltst (void) 289 { 290 mpfr_exp_t emin, emax; 291 292 ext = 0; 293 test_small (); 294 test_large_small (); 295 check_overflow (); 296 297 emin = mpfr_get_emin (); 298 emax = mpfr_get_emax (); 299 set_emin (MPFR_EMIN_MIN); 300 set_emax (MPFR_EMAX_MAX); 301 if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) 302 { 303 ext = 1; 304 test_small (); 305 test_large_small (); 306 check_overflow (); 307 set_emin (emin); 308 set_emax (emax); 309 } 310 } 311 312 int 313 main (int argc, char *argv[]) 314 { 315 tests_start_mpfr (); 316 317 special (); 318 319 test_large (); 320 alltst (); 321 322 test_generic (2, 100, 10); 323 324 tests_end_mpfr (); 325 return 0; 326 } 327