1 1.1 mrg /* Test file for mpfr_hypot. 2 1.1 mrg 3 1.1.1.6 mrg Copyright 2001-2023 Free Software Foundation, Inc. 4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA. 5 1.1 mrg 6 1.1 mrg This file is part of the GNU MPFR Library. 7 1.1 mrg 8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify 9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by 10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your 11 1.1 mrg option) any later version. 12 1.1 mrg 13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but 14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 1.1 mrg License for more details. 17 1.1 mrg 18 1.1 mrg You should have received a copy of the GNU Lesser General Public License 19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 1.1.1.5 mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 1.1 mrg 23 1.1 mrg #include "mpfr-test.h" 24 1.1 mrg 25 1.1 mrg /* Non-zero when extended exponent range */ 26 1.1 mrg static int ext = 0; 27 1.1 mrg 28 1.1 mrg static void 29 1.1 mrg special (void) 30 1.1 mrg { 31 1.1 mrg mpfr_t x, y, z; 32 1.1 mrg 33 1.1 mrg mpfr_init (x); 34 1.1 mrg mpfr_init (y); 35 1.1 mrg mpfr_init (z); 36 1.1 mrg 37 1.1 mrg mpfr_set_nan (x); 38 1.1.1.3 mrg mpfr_set_ui (y, 0, MPFR_RNDN); 39 1.1.1.3 mrg mpfr_hypot (z, x, x, MPFR_RNDN); 40 1.1.1.3 mrg MPFR_ASSERTN(mpfr_nan_p (z)); 41 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN); 42 1.1 mrg MPFR_ASSERTN(mpfr_nan_p (z)); 43 1.1.1.3 mrg mpfr_hypot (z, y, x, MPFR_RNDN); 44 1.1.1.3 mrg MPFR_ASSERTN(mpfr_nan_p (z)); 45 1.1 mrg 46 1.1 mrg mpfr_set_inf (x, 1); 47 1.1 mrg mpfr_set_inf (y, -1); 48 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN); 49 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 50 1.1 mrg 51 1.1 mrg mpfr_set_inf (x, -1); 52 1.1 mrg mpfr_set_nan (y); 53 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN); 54 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 55 1.1 mrg 56 1.1 mrg mpfr_set_nan (x); 57 1.1 mrg mpfr_set_inf (y, -1); 58 1.1 mrg mpfr_hypot (z, x, y, MPFR_RNDN); 59 1.1 mrg MPFR_ASSERTN(mpfr_inf_p (z) && mpfr_sgn (z) > 0); 60 1.1 mrg 61 1.1 mrg mpfr_clear (x); 62 1.1 mrg mpfr_clear (y); 63 1.1 mrg mpfr_clear (z); 64 1.1 mrg } 65 1.1 mrg 66 1.1 mrg static void 67 1.1 mrg test_large (void) 68 1.1 mrg { 69 1.1 mrg mpfr_t x, y, z, t; 70 1.1 mrg 71 1.1 mrg mpfr_init (x); 72 1.1 mrg mpfr_init (y); 73 1.1 mrg mpfr_init (z); 74 1.1 mrg mpfr_init (t); 75 1.1 mrg 76 1.1 mrg mpfr_set_ui (x, 21, MPFR_RNDN); 77 1.1 mrg mpfr_set_ui (y, 28, MPFR_RNDN); 78 1.1 mrg mpfr_set_ui (z, 35, MPFR_RNDN); 79 1.1 mrg 80 1.1 mrg mpfr_mul_2ui (x, x, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 81 1.1 mrg mpfr_mul_2ui (y, y, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 82 1.1 mrg mpfr_mul_2ui (z, z, MPFR_EMAX_DEFAULT-6, MPFR_RNDN); 83 1.1 mrg 84 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN); 85 1.1 mrg if (mpfr_cmp (z, t)) 86 1.1 mrg { 87 1.1 mrg printf ("Error in test_large: got\n"); 88 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 89 1.1 mrg printf ("\ninstead of\n"); 90 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 91 1.1 mrg printf ("\n"); 92 1.1 mrg exit (1); 93 1.1 mrg } 94 1.1 mrg 95 1.1 mrg mpfr_set_prec (x, 53); 96 1.1 mrg mpfr_set_prec (t, 53); 97 1.1 mrg mpfr_set_prec (y, 53); 98 1.1 mrg mpfr_set_str_binary (x, "0.11101100011110000011101000010101010011001101000001100E-1021"); 99 1.1 mrg mpfr_set_str_binary (y, "0.11111001010011000001110110001101011100001000010010100E-1021"); 100 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN); 101 1.1 mrg mpfr_set_str_binary (z, "0.101010111100110111101110111110100110010011001010111E-1020"); 102 1.1 mrg if (mpfr_cmp (z, t)) 103 1.1 mrg { 104 1.1 mrg printf ("Error in test_large: got\n"); 105 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 106 1.1 mrg printf ("\ninstead of\n"); 107 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 108 1.1 mrg printf ("\n"); 109 1.1 mrg exit (1); 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg mpfr_set_prec (x, 240); 113 1.1 mrg mpfr_set_prec (y, 22); 114 1.1 mrg mpfr_set_prec (z, 2); 115 1.1 mrg mpfr_set_prec (t, 2); 116 1.1 mrg mpfr_set_str_binary (x, "0.100111011010010010110100000100000001100010011100110101101111111101011110111011011101010110100101111000111100010100110000100101011110111011100110100110100101110101101100011000001100000001111101110100100100011011011010110111100110010101000111e-7"); 117 1.1 mrg mpfr_set_str_binary (y, "0.1111000010000011000111E-10"); 118 1.1 mrg mpfr_hypot (t, x, y, MPFR_RNDN); 119 1.1 mrg mpfr_set_str_binary (z, "0.11E-7"); 120 1.1 mrg if (mpfr_cmp (z, t)) 121 1.1 mrg { 122 1.1 mrg printf ("Error in test_large: got\n"); 123 1.1 mrg mpfr_out_str (stdout, 2, 0, t, MPFR_RNDN); 124 1.1 mrg printf ("\ninstead of\n"); 125 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 126 1.1 mrg printf ("\n"); 127 1.1 mrg exit (1); 128 1.1 mrg } 129 1.1 mrg 130 1.1 mrg mpfr_clear (x); 131 1.1 mrg mpfr_clear (y); 132 1.1 mrg mpfr_clear (z); 133 1.1 mrg mpfr_clear (t); 134 1.1 mrg } 135 1.1 mrg 136 1.1 mrg static void 137 1.1 mrg test_small (void) 138 1.1 mrg { 139 1.1 mrg mpfr_t x, y, z1, z2; 140 1.1 mrg int inex1, inex2; 141 1.1 mrg unsigned int flags; 142 1.1 mrg 143 1.1 mrg /* Test hypot(x,x) with x = 2^(emin-1). Result is x * sqrt(2). */ 144 1.1 mrg mpfr_inits2 (8, x, y, z1, z2, (mpfr_ptr) 0); 145 1.1 mrg mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN); 146 1.1 mrg mpfr_set_si_2exp (y, 1, mpfr_get_emin () - 1, MPFR_RNDN); 147 1.1 mrg mpfr_set_ui (z1, 2, MPFR_RNDN); 148 1.1 mrg inex1 = mpfr_sqrt (z1, z1, MPFR_RNDN); 149 1.1 mrg inex2 = mpfr_mul (z1, z1, x, MPFR_RNDN); 150 1.1 mrg MPFR_ASSERTN (inex2 == 0); 151 1.1 mrg mpfr_clear_flags (); 152 1.1 mrg inex2 = mpfr_hypot (z2, x, y, MPFR_RNDN); 153 1.1 mrg flags = __gmpfr_flags; 154 1.1 mrg if (mpfr_cmp (z1, z2) != 0) 155 1.1 mrg { 156 1.1 mrg printf ("Error in test_small%s\nExpected ", 157 1.1 mrg ext ? ", extended exponent range" : ""); 158 1.1 mrg mpfr_out_str (stdout, 2, 0, z1, MPFR_RNDN); 159 1.1 mrg printf ("\nGot "); 160 1.1 mrg mpfr_out_str (stdout, 2, 0, z2, MPFR_RNDN); 161 1.1 mrg printf ("\n"); 162 1.1 mrg exit (1); 163 1.1 mrg } 164 1.1 mrg if (! SAME_SIGN (inex1, inex2)) 165 1.1 mrg { 166 1.1 mrg printf ("Bad ternary value in test_small%s\nExpected %d, got %d\n", 167 1.1 mrg ext ? ", extended exponent range" : "", inex1, inex2); 168 1.1 mrg exit (1); 169 1.1 mrg } 170 1.1 mrg if (flags != MPFR_FLAGS_INEXACT) 171 1.1 mrg { 172 1.1 mrg printf ("Bad flags in test_small%s\nExpected %u, got %u\n", 173 1.1 mrg ext ? ", extended exponent range" : "", 174 1.1 mrg (unsigned int) MPFR_FLAGS_INEXACT, flags); 175 1.1 mrg exit (1); 176 1.1 mrg } 177 1.1 mrg mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0); 178 1.1 mrg } 179 1.1 mrg 180 1.1 mrg static void 181 1.1 mrg test_large_small (void) 182 1.1 mrg { 183 1.1 mrg mpfr_t x, y, z; 184 1.1 mrg int inexact, inex2, r; 185 1.1 mrg 186 1.1 mrg mpfr_init2 (x, 3); 187 1.1 mrg mpfr_init2 (y, 2); 188 1.1 mrg mpfr_init2 (z, 2); 189 1.1 mrg 190 1.1 mrg mpfr_set_ui_2exp (x, 1, mpfr_get_emax () / 2, MPFR_RNDN); 191 1.1 mrg mpfr_set_ui_2exp (y, 1, -1, MPFR_RNDN); 192 1.1 mrg inexact = mpfr_hypot (z, x, y, MPFR_RNDN); 193 1.1 mrg if (inexact >= 0 || mpfr_cmp (x, z)) 194 1.1 mrg { 195 1.1 mrg printf ("Error 1 in test_large_small%s\n", 196 1.1 mrg ext ? ", extended exponent range" : ""); 197 1.1 mrg exit (1); 198 1.1 mrg } 199 1.1 mrg 200 1.1 mrg mpfr_mul_ui (x, x, 5, MPFR_RNDN); 201 1.1 mrg inexact = mpfr_hypot (z, x, y, MPFR_RNDN); 202 1.1 mrg if (mpfr_cmp (x, z) >= 0) 203 1.1 mrg { 204 1.1 mrg printf ("Error 2 in test_large_small%s\n", 205 1.1 mrg ext ? ", extended exponent range" : ""); 206 1.1 mrg printf ("x = "); 207 1.1 mrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 208 1.1 mrg printf ("\n"); 209 1.1 mrg printf ("y = "); 210 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 211 1.1 mrg printf ("\n"); 212 1.1 mrg printf ("z = "); 213 1.1 mrg mpfr_out_str (stdout, 2, 0, z, MPFR_RNDN); 214 1.1 mrg printf (" (in precision 2) instead of\n "); 215 1.1 mrg mpfr_out_str (stdout, 2, 2, x, MPFR_RNDU); 216 1.1 mrg printf ("\n"); 217 1.1 mrg exit (1); 218 1.1 mrg } 219 1.1 mrg 220 1.1 mrg RND_LOOP(r) 221 1.1 mrg { 222 1.1 mrg mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN); 223 1.1 mrg mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN); 224 1.1 mrg inexact = mpfr_hypot (z, x, y, (mpfr_rnd_t) r); 225 1.1 mrg inex2 = mpfr_add_ui (y, x, 1, (mpfr_rnd_t) r); 226 1.1 mrg if (! mpfr_equal_p (y, z) || ! SAME_SIGN (inexact, inex2)) 227 1.1 mrg { 228 1.1 mrg printf ("Error 3 in test_large_small, %s%s\n", 229 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), 230 1.1 mrg ext ? ", extended exponent range" : ""); 231 1.1 mrg printf ("Expected "); 232 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 233 1.1 mrg printf (", inex = %d\n", inex2); 234 1.1 mrg printf ("Got "); 235 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN); 236 1.1 mrg printf (", inex = %d\n", inexact); 237 1.1 mrg exit (1); 238 1.1 mrg } 239 1.1 mrg } 240 1.1 mrg 241 1.1 mrg mpfr_clear (x); 242 1.1 mrg mpfr_clear (y); 243 1.1 mrg mpfr_clear (z); 244 1.1 mrg } 245 1.1 mrg 246 1.1 mrg static void 247 1.1 mrg check_overflow (void) 248 1.1 mrg { 249 1.1 mrg mpfr_t x, y; 250 1.1 mrg int inex, r; 251 1.1 mrg 252 1.1 mrg mpfr_inits2 (8, x, y, (mpfr_ptr) 0); 253 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN); 254 1.1 mrg mpfr_setmax (x, mpfr_get_emax ()); 255 1.1 mrg 256 1.1 mrg RND_LOOP(r) 257 1.1 mrg { 258 1.1 mrg mpfr_clear_overflow (); 259 1.1 mrg inex = mpfr_hypot (y, x, x, (mpfr_rnd_t) r); 260 1.1 mrg if (!mpfr_overflow_p ()) 261 1.1 mrg { 262 1.1 mrg printf ("No overflow in check_overflow for %s%s\n", 263 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r), 264 1.1 mrg ext ? ", extended exponent range" : ""); 265 1.1 mrg exit (1); 266 1.1 mrg } 267 1.1 mrg MPFR_ASSERTN (MPFR_IS_POS (y)); 268 1.1 mrg if (r == MPFR_RNDZ || r == MPFR_RNDD) 269 1.1 mrg { 270 1.1 mrg MPFR_ASSERTN (inex < 0); 271 1.1 mrg MPFR_ASSERTN (!mpfr_inf_p (y)); 272 1.1 mrg mpfr_nexttoinf (y); 273 1.1 mrg } 274 1.1 mrg else 275 1.1 mrg { 276 1.1 mrg MPFR_ASSERTN (inex > 0); 277 1.1 mrg } 278 1.1 mrg MPFR_ASSERTN (mpfr_inf_p (y)); 279 1.1 mrg } 280 1.1 mrg 281 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0); 282 1.1 mrg } 283 1.1 mrg 284 1.1 mrg #define TWO_ARGS 285 1.1 mrg #define TEST_FUNCTION mpfr_hypot 286 1.1 mrg #include "tgeneric.c" 287 1.1 mrg 288 1.1 mrg static void 289 1.1 mrg alltst (void) 290 1.1 mrg { 291 1.1 mrg mpfr_exp_t emin, emax; 292 1.1 mrg 293 1.1 mrg ext = 0; 294 1.1 mrg test_small (); 295 1.1 mrg test_large_small (); 296 1.1 mrg check_overflow (); 297 1.1 mrg 298 1.1 mrg emin = mpfr_get_emin (); 299 1.1 mrg emax = mpfr_get_emax (); 300 1.1 mrg set_emin (MPFR_EMIN_MIN); 301 1.1 mrg set_emax (MPFR_EMAX_MAX); 302 1.1 mrg if (mpfr_get_emin () != emin || mpfr_get_emax () != emax) 303 1.1 mrg { 304 1.1 mrg ext = 1; 305 1.1 mrg test_small (); 306 1.1 mrg test_large_small (); 307 1.1 mrg check_overflow (); 308 1.1 mrg set_emin (emin); 309 1.1 mrg set_emax (emax); 310 1.1 mrg } 311 1.1 mrg } 312 1.1 mrg 313 1.1.1.4 mrg /* Test failing with GMP_CHECK_RANDOMIZE=1513841234 (overflow flag not set). 314 1.1.1.4 mrg The bug was in fact in mpfr_nexttoinf which didn't set the overflow flag. */ 315 1.1.1.4 mrg static void 316 1.1.1.4 mrg bug20171221 (void) 317 1.1.1.4 mrg { 318 1.1.1.4 mrg mpfr_t x, u, y; 319 1.1.1.4 mrg int inex; 320 1.1.1.4 mrg mpfr_exp_t emax; 321 1.1.1.4 mrg 322 1.1.1.4 mrg mpfr_init2 (x, 12); 323 1.1.1.4 mrg mpfr_init2 (u, 12); 324 1.1.1.4 mrg mpfr_init2 (y, 11); 325 1.1.1.4 mrg mpfr_set_str_binary (x, "0.111111111110E0"); 326 1.1.1.4 mrg mpfr_set_str_binary (u, "0.111011110100E-177"); 327 1.1.1.4 mrg emax = mpfr_get_emax (); 328 1.1.1.6 mrg set_emax (0); 329 1.1.1.4 mrg mpfr_clear_flags (); 330 1.1.1.4 mrg inex = mpfr_hypot (y, x, u, MPFR_RNDU); 331 1.1.1.4 mrg MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0); 332 1.1.1.4 mrg MPFR_ASSERTN(inex > 0); 333 1.1.1.4 mrg MPFR_ASSERTN(mpfr_inexflag_p ()); 334 1.1.1.4 mrg MPFR_ASSERTN(mpfr_overflow_p ()); 335 1.1.1.6 mrg set_emax (emax); 336 1.1.1.6 mrg mpfr_clear (x); 337 1.1.1.6 mrg mpfr_clear (u); 338 1.1.1.6 mrg mpfr_clear (y); 339 1.1.1.6 mrg } 340 1.1.1.6 mrg 341 1.1.1.6 mrg /* check overflow for x=0xf.ffffffffffff8p+1020 and u=0xf.fffffp+124 342 1.1.1.6 mrg with rounding upwards and emax=1024 (as in binary64) */ 343 1.1.1.6 mrg static void 344 1.1.1.6 mrg test_overflow (void) 345 1.1.1.6 mrg { 346 1.1.1.6 mrg mpfr_t x, u, y; 347 1.1.1.6 mrg int inex; 348 1.1.1.6 mrg mpfr_exp_t emax; 349 1.1.1.6 mrg 350 1.1.1.6 mrg mpfr_init2 (x, 53); 351 1.1.1.6 mrg mpfr_init2 (u, 53); 352 1.1.1.6 mrg mpfr_init2 (y, 53); 353 1.1.1.6 mrg mpfr_set_str (x, "0xf.ffffffffffff8p+1020", 16, MPFR_RNDN); 354 1.1.1.6 mrg mpfr_set_str (u, "0xf.fffffp+124", 16, MPFR_RNDN); 355 1.1.1.6 mrg emax = mpfr_get_emax (); 356 1.1.1.6 mrg set_emax (1024); 357 1.1.1.6 mrg mpfr_clear_flags (); 358 1.1.1.6 mrg inex = mpfr_hypot (y, x, u, MPFR_RNDU); 359 1.1.1.6 mrg MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0); 360 1.1.1.6 mrg MPFR_ASSERTN(inex > 0); 361 1.1.1.6 mrg MPFR_ASSERTN(mpfr_inexflag_p ()); 362 1.1.1.6 mrg MPFR_ASSERTN(mpfr_overflow_p ()); 363 1.1.1.6 mrg set_emax (emax); 364 1.1.1.4 mrg mpfr_clear (x); 365 1.1.1.4 mrg mpfr_clear (u); 366 1.1.1.4 mrg mpfr_clear (y); 367 1.1.1.4 mrg } 368 1.1.1.4 mrg 369 1.1 mrg int 370 1.1 mrg main (int argc, char *argv[]) 371 1.1 mrg { 372 1.1 mrg tests_start_mpfr (); 373 1.1 mrg 374 1.1.1.4 mrg bug20171221 (); 375 1.1 mrg special (); 376 1.1 mrg 377 1.1 mrg test_large (); 378 1.1 mrg alltst (); 379 1.1.1.6 mrg test_overflow (); 380 1.1 mrg 381 1.1.1.4 mrg test_generic (MPFR_PREC_MIN, 100, 10); 382 1.1 mrg 383 1.1 mrg tests_end_mpfr (); 384 1.1 mrg return 0; 385 1.1 mrg } 386