1 1.1 mrg /* Test file for mpfr_sqrt. 2 1.1 mrg 3 1.1.1.6 mrg Copyright 1999, 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 #ifdef CHECK_EXTERNAL 26 1.1 mrg static int 27 1.1 mrg test_sqrt (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) 28 1.1 mrg { 29 1.1 mrg int res; 30 1.1 mrg int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b); 31 1.1 mrg if (ok) 32 1.1 mrg { 33 1.1 mrg mpfr_print_raw (b); 34 1.1 mrg } 35 1.1 mrg res = mpfr_sqrt (a, b, rnd_mode); 36 1.1 mrg if (ok) 37 1.1 mrg { 38 1.1 mrg printf (" "); 39 1.1 mrg mpfr_print_raw (a); 40 1.1 mrg printf ("\n"); 41 1.1 mrg } 42 1.1 mrg return res; 43 1.1 mrg } 44 1.1 mrg #else 45 1.1 mrg #define test_sqrt mpfr_sqrt 46 1.1 mrg #endif 47 1.1 mrg 48 1.1 mrg static void 49 1.1 mrg check3 (const char *as, mpfr_rnd_t rnd_mode, const char *qs) 50 1.1 mrg { 51 1.1 mrg mpfr_t q; 52 1.1 mrg 53 1.1 mrg mpfr_init2 (q, 53); 54 1.1 mrg mpfr_set_str1 (q, as); 55 1.1 mrg test_sqrt (q, q, rnd_mode); 56 1.1 mrg if (mpfr_cmp_str1 (q, qs) ) 57 1.1 mrg { 58 1.1 mrg printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n", 59 1.1 mrg as, mpfr_print_rnd_mode (rnd_mode)); 60 1.1 mrg printf ("expected sqrt is %s, got ",qs); 61 1.1 mrg mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); 62 1.1 mrg putchar ('\n'); 63 1.1 mrg exit (1); 64 1.1 mrg } 65 1.1 mrg mpfr_clear (q); 66 1.1 mrg } 67 1.1 mrg 68 1.1 mrg static void 69 1.1.1.4 mrg check4 (const char *as, mpfr_rnd_t rnd_mode, const char *qs) 70 1.1 mrg { 71 1.1 mrg mpfr_t q; 72 1.1 mrg 73 1.1 mrg mpfr_init2 (q, 53); 74 1.1 mrg mpfr_set_str1 (q, as); 75 1.1 mrg test_sqrt (q, q, rnd_mode); 76 1.1.1.4 mrg if (mpfr_cmp_str (q, qs, 16, MPFR_RNDN)) 77 1.1 mrg { 78 1.1 mrg printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n", 79 1.1.1.4 mrg as, mpfr_print_rnd_mode (rnd_mode)); 80 1.1.1.4 mrg printf ("expected %s\ngot ", qs); 81 1.1 mrg mpfr_out_str (stdout, 16, 0, q, MPFR_RNDN); 82 1.1.1.4 mrg printf ("\n"); 83 1.1 mrg mpfr_clear (q); 84 1.1 mrg exit (1); 85 1.1 mrg } 86 1.1 mrg mpfr_clear (q); 87 1.1 mrg } 88 1.1 mrg 89 1.1 mrg static void 90 1.1 mrg check24 (const char *as, mpfr_rnd_t rnd_mode, const char *qs) 91 1.1 mrg { 92 1.1 mrg mpfr_t q; 93 1.1 mrg 94 1.1 mrg mpfr_init2 (q, 24); 95 1.1 mrg mpfr_set_str1 (q, as); 96 1.1 mrg test_sqrt (q, q, rnd_mode); 97 1.1 mrg if (mpfr_cmp_str1 (q, qs)) 98 1.1 mrg { 99 1.1 mrg printf ("mpfr_sqrt failed for a=%s, prec=24, rnd_mode=%s\n", 100 1.1 mrg as, mpfr_print_rnd_mode(rnd_mode)); 101 1.1 mrg printf ("expected sqrt is %s, got ",qs); 102 1.1 mrg mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); 103 1.1 mrg printf ("\n"); 104 1.1 mrg exit (1); 105 1.1 mrg } 106 1.1 mrg mpfr_clear (q); 107 1.1 mrg } 108 1.1 mrg 109 1.1 mrg static void 110 1.1 mrg check_diverse (const char *as, mpfr_prec_t p, const char *qs) 111 1.1 mrg { 112 1.1 mrg mpfr_t q; 113 1.1 mrg 114 1.1 mrg mpfr_init2 (q, p); 115 1.1 mrg mpfr_set_str1 (q, as); 116 1.1 mrg test_sqrt (q, q, MPFR_RNDN); 117 1.1 mrg if (mpfr_cmp_str1 (q, qs)) 118 1.1 mrg { 119 1.1 mrg printf ("mpfr_sqrt failed for a=%s, prec=%lu, rnd_mode=%s\n", 120 1.1.1.2 mrg as, (unsigned long) p, mpfr_print_rnd_mode (MPFR_RNDN)); 121 1.1 mrg printf ("expected sqrt is %s, got ", qs); 122 1.1 mrg mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN); 123 1.1 mrg printf ("\n"); 124 1.1 mrg exit (1); 125 1.1 mrg } 126 1.1 mrg mpfr_clear (q); 127 1.1 mrg } 128 1.1 mrg 129 1.1 mrg /* the following examples come from the paper "Number-theoretic Test 130 1.1 mrg Generation for Directed Rounding" from Michael Parks, Table 3 */ 131 1.1 mrg static void 132 1.1 mrg check_float (void) 133 1.1 mrg { 134 1.1 mrg check24("70368760954880.0", MPFR_RNDN, "8.388609e6"); 135 1.1 mrg check24("281474943156224.0", MPFR_RNDN, "1.6777215e7"); 136 1.1 mrg check24("70368777732096.0", MPFR_RNDN, "8.388610e6"); 137 1.1 mrg check24("281474909601792.0", MPFR_RNDN, "1.6777214e7"); 138 1.1 mrg check24("100216216748032.0", MPFR_RNDN, "1.0010805e7"); 139 1.1 mrg check24("120137273311232.0", MPFR_RNDN, "1.0960715e7"); 140 1.1 mrg check24("229674600890368.0", MPFR_RNDN, "1.5155019e7"); 141 1.1 mrg check24("70368794509312.0", MPFR_RNDN, "8.388611e6"); 142 1.1 mrg check24("281474876047360.0", MPFR_RNDN, "1.6777213e7"); 143 1.1 mrg check24("91214552498176.0", MPFR_RNDN, "9.550631e6"); 144 1.1 mrg 145 1.1 mrg check24("70368760954880.0", MPFR_RNDZ, "8.388608e6"); 146 1.1 mrg check24("281474943156224.0", MPFR_RNDZ, "1.6777214e7"); 147 1.1 mrg check24("70368777732096.0", MPFR_RNDZ, "8.388609e6"); 148 1.1 mrg check24("281474909601792.0", MPFR_RNDZ, "1.6777213e7"); 149 1.1 mrg check24("100216216748032.0", MPFR_RNDZ, "1.0010805e7"); 150 1.1 mrg check24("120137273311232.0", MPFR_RNDZ, "1.0960715e7"); 151 1.1 mrg check24("229674600890368.0", MPFR_RNDZ, "1.5155019e7"); 152 1.1 mrg check24("70368794509312.0", MPFR_RNDZ, "8.38861e6"); 153 1.1 mrg check24("281474876047360.0", MPFR_RNDZ, "1.6777212e7"); 154 1.1 mrg check24("91214552498176.0", MPFR_RNDZ, "9.550631e6"); 155 1.1 mrg 156 1.1 mrg check24("70368760954880.0", MPFR_RNDU, "8.388609e6"); 157 1.1 mrg check24("281474943156224.0",MPFR_RNDU, "1.6777215e7"); 158 1.1 mrg check24("70368777732096.0", MPFR_RNDU, "8.388610e6"); 159 1.1 mrg check24("281474909601792.0", MPFR_RNDU, "1.6777214e7"); 160 1.1 mrg check24("100216216748032.0", MPFR_RNDU, "1.0010806e7"); 161 1.1 mrg check24("120137273311232.0", MPFR_RNDU, "1.0960716e7"); 162 1.1 mrg check24("229674600890368.0", MPFR_RNDU, "1.515502e7"); 163 1.1 mrg check24("70368794509312.0", MPFR_RNDU, "8.388611e6"); 164 1.1 mrg check24("281474876047360.0", MPFR_RNDU, "1.6777213e7"); 165 1.1 mrg check24("91214552498176.0", MPFR_RNDU, "9.550632e6"); 166 1.1 mrg 167 1.1 mrg check24("70368760954880.0", MPFR_RNDD, "8.388608e6"); 168 1.1 mrg check24("281474943156224.0", MPFR_RNDD, "1.6777214e7"); 169 1.1 mrg check24("70368777732096.0", MPFR_RNDD, "8.388609e6"); 170 1.1 mrg check24("281474909601792.0", MPFR_RNDD, "1.6777213e7"); 171 1.1 mrg check24("100216216748032.0", MPFR_RNDD, "1.0010805e7"); 172 1.1 mrg check24("120137273311232.0", MPFR_RNDD, "1.0960715e7"); 173 1.1 mrg check24("229674600890368.0", MPFR_RNDD, "1.5155019e7"); 174 1.1 mrg check24("70368794509312.0", MPFR_RNDD, "8.38861e6"); 175 1.1 mrg check24("281474876047360.0", MPFR_RNDD, "1.6777212e7"); 176 1.1 mrg check24("91214552498176.0", MPFR_RNDD, "9.550631e6"); 177 1.1 mrg 178 1.1.1.6 mrg /* check that rounding away is just rounding toward positive infinity */ 179 1.1 mrg check24("91214552498176.0", MPFR_RNDA, "9.550632e6"); 180 1.1 mrg } 181 1.1 mrg 182 1.1 mrg static void 183 1.1 mrg special (void) 184 1.1 mrg { 185 1.1 mrg mpfr_t x, y, z; 186 1.1 mrg int inexact; 187 1.1 mrg mpfr_prec_t p; 188 1.1 mrg 189 1.1 mrg mpfr_init (x); 190 1.1 mrg mpfr_init (y); 191 1.1 mrg mpfr_init (z); 192 1.1 mrg 193 1.1 mrg mpfr_set_prec (x, 64); 194 1.1 mrg mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1"); 195 1.1 mrg mpfr_set_prec (y, 32); 196 1.1 mrg test_sqrt (y, x, MPFR_RNDN); 197 1.1 mrg if (mpfr_cmp_ui (y, 2405743844UL)) 198 1.1 mrg { 199 1.1 mrg printf ("Error for n^2+n+1/2 with n=2405743843\n"); 200 1.1 mrg exit (1); 201 1.1 mrg } 202 1.1 mrg 203 1.1 mrg mpfr_set_prec (x, 65); 204 1.1 mrg mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2"); 205 1.1 mrg mpfr_set_prec (y, 32); 206 1.1 mrg test_sqrt (y, x, MPFR_RNDN); 207 1.1 mrg if (mpfr_cmp_ui (y, 2405743844UL)) 208 1.1 mrg { 209 1.1 mrg printf ("Error for n^2+n+1/4 with n=2405743843\n"); 210 1.1 mrg mpfr_dump (y); 211 1.1 mrg exit (1); 212 1.1 mrg } 213 1.1 mrg 214 1.1 mrg mpfr_set_prec (x, 66); 215 1.1 mrg mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3"); 216 1.1 mrg mpfr_set_prec (y, 32); 217 1.1 mrg test_sqrt (y, x, MPFR_RNDN); 218 1.1 mrg if (mpfr_cmp_ui (y, 2405743844UL)) 219 1.1 mrg { 220 1.1 mrg printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n"); 221 1.1 mrg mpfr_dump (y); 222 1.1 mrg exit (1); 223 1.1 mrg } 224 1.1 mrg 225 1.1 mrg mpfr_set_prec (x, 66); 226 1.1 mrg mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3"); 227 1.1 mrg mpfr_set_prec (y, 32); 228 1.1 mrg test_sqrt (y, x, MPFR_RNDN); 229 1.1 mrg if (mpfr_cmp_ui (y, 2405743843UL)) 230 1.1 mrg { 231 1.1 mrg printf ("Error for n^2+n+1/8 with n=2405743843\n"); 232 1.1 mrg mpfr_dump (y); 233 1.1 mrg exit (1); 234 1.1 mrg } 235 1.1 mrg 236 1.1 mrg mpfr_set_prec (x, 27); 237 1.1 mrg mpfr_set_str_binary (x, "0.110100111010101000010001011"); 238 1.1 mrg if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0) 239 1.1 mrg { 240 1.1 mrg printf ("Wrong inexact flag: expected -1, got %d\n", inexact); 241 1.1 mrg exit (1); 242 1.1 mrg } 243 1.1 mrg 244 1.1 mrg mpfr_set_prec (x, 2); 245 1.1 mrg for (p=2; p<1000; p++) 246 1.1 mrg { 247 1.1 mrg mpfr_set_prec (z, p); 248 1.1 mrg mpfr_set_ui (z, 1, MPFR_RNDN); 249 1.1 mrg mpfr_nexttoinf (z); 250 1.1 mrg test_sqrt (x, z, MPFR_RNDU); 251 1.1 mrg if (mpfr_cmp_ui_2exp(x, 3, -1)) 252 1.1 mrg { 253 1.1 mrg printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n", 254 1.1 mrg (unsigned int) p); 255 1.1.1.4 mrg printf ("got "); mpfr_dump (x); 256 1.1 mrg exit (1); 257 1.1 mrg } 258 1.1 mrg } 259 1.1 mrg 260 1.1 mrg /* check inexact flag */ 261 1.1 mrg mpfr_set_prec (x, 5); 262 1.1 mrg mpfr_set_str_binary (x, "1.1001E-2"); 263 1.1 mrg if ((inexact = test_sqrt (x, x, MPFR_RNDN))) 264 1.1 mrg { 265 1.1 mrg printf ("Wrong inexact flag: expected 0, got %d\n", inexact); 266 1.1 mrg exit (1); 267 1.1 mrg } 268 1.1 mrg 269 1.1 mrg mpfr_set_prec (x, 2); 270 1.1 mrg mpfr_set_prec (z, 2); 271 1.1 mrg 272 1.1 mrg /* checks the sign is correctly set */ 273 1.1 mrg mpfr_set_si (x, 1, MPFR_RNDN); 274 1.1 mrg mpfr_set_si (z, -1, MPFR_RNDN); 275 1.1 mrg test_sqrt (z, x, MPFR_RNDN); 276 1.1 mrg if (mpfr_cmp_ui (z, 0) < 0) 277 1.1 mrg { 278 1.1 mrg printf ("Error: square root of 1 gives "); 279 1.1.1.4 mrg mpfr_dump (z); 280 1.1 mrg exit (1); 281 1.1 mrg } 282 1.1 mrg 283 1.1 mrg mpfr_set_prec (x, 192); 284 1.1 mrg mpfr_set_prec (z, 160); 285 1.1 mrg mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1"); 286 1.1 mrg mpfr_set_prec (x, 160); 287 1.1 mrg test_sqrt(x, z, MPFR_RNDN); 288 1.1 mrg test_sqrt(z, x, MPFR_RNDN); 289 1.1 mrg 290 1.1 mrg mpfr_set_prec (x, 53); 291 1.1 mrg mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN); 292 1.1.1.5 mrg mpfr_div_2ui (x, x, 1075, MPFR_RNDN); 293 1.1 mrg test_sqrt (x, x, MPFR_RNDN); 294 1.1 mrg mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN); 295 1.1 mrg if (mpfr_cmp (x, z)) 296 1.1 mrg { 297 1.1 mrg printf ("Error: square root of 8093416094703476*2^(-1075)\n"); 298 1.1 mrg printf ("expected "); mpfr_dump (z); 299 1.1 mrg printf ("got "); mpfr_dump (x); 300 1.1 mrg exit (1); 301 1.1 mrg } 302 1.1 mrg 303 1.1 mrg mpfr_set_prec (x, 33); 304 1.1 mrg mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10"); 305 1.1 mrg mpfr_set_prec (z, 157); 306 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDN); 307 1.1 mrg mpfr_set_prec (x, 157); 308 1.1 mrg mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5"); 309 1.1 mrg if (mpfr_cmp (x, z)) 310 1.1 mrg { 311 1.1 mrg printf ("Error: square root (1)\n"); 312 1.1 mrg exit (1); 313 1.1 mrg } 314 1.1 mrg if (inexact <= 0) 315 1.1 mrg { 316 1.1 mrg printf ("Error: wrong inexact flag (1)\n"); 317 1.1 mrg exit (1); 318 1.1 mrg } 319 1.1 mrg 320 1.1 mrg /* case prec(result) << prec(input) */ 321 1.1 mrg mpfr_set_prec (z, 2); 322 1.1.1.4 mrg for (p = mpfr_get_prec (z); p < 1000; p++) 323 1.1 mrg { 324 1.1 mrg mpfr_set_prec (x, p); 325 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN); 326 1.1 mrg mpfr_nextabove (x); 327 1.1 mrg /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */ 328 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDN); 329 1.1 mrg MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); 330 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDZ); 331 1.1 mrg MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); 332 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDU); 333 1.1 mrg MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0); 334 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDD); 335 1.1 mrg MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0); 336 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDA); 337 1.1 mrg MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0); 338 1.1 mrg } 339 1.1 mrg 340 1.1 mrg /* corner case rw = 0 in rounding to nearest */ 341 1.1 mrg mpfr_set_prec (z, GMP_NUMB_BITS - 1); 342 1.1 mrg mpfr_set_prec (y, GMP_NUMB_BITS - 1); 343 1.1 mrg mpfr_set_ui (y, 1, MPFR_RNDN); 344 1.1.1.5 mrg mpfr_mul_2ui (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN); 345 1.1 mrg mpfr_nextabove (y); 346 1.1 mrg for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++) 347 1.1 mrg { 348 1.1 mrg mpfr_set_prec (x, p); 349 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN); 350 1.1 mrg mpfr_set_exp (x, GMP_NUMB_BITS); 351 1.1 mrg mpfr_add_ui (x, x, 1, MPFR_RNDN); 352 1.1 mrg /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */ 353 1.1.1.6 mrg inexact = mpfr_sqr (x, x, MPFR_RNDN); 354 1.1.1.4 mrg MPFR_ASSERTN (inexact == 0); /* exact */ 355 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDN); 356 1.1 mrg /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */ 357 1.1 mrg MPFR_ASSERTN (inexact < 0); 358 1.1.1.4 mrg inexact = mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1); 359 1.1.1.4 mrg MPFR_ASSERTN (inexact == 0); 360 1.1 mrg mpfr_nextbelow (x); 361 1.1 mrg /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */ 362 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDN); 363 1.1 mrg MPFR_ASSERTN(inexact < 0 && 364 1.1 mrg mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0); 365 1.1 mrg mpfr_nextabove (x); 366 1.1 mrg mpfr_nextabove (x); 367 1.1 mrg /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */ 368 1.1 mrg inexact = test_sqrt (z, x, MPFR_RNDN); 369 1.1 mrg if (mpfr_cmp (z, y)) 370 1.1 mrg { 371 1.1 mrg printf ("Error for sqrt(x) in rounding to nearest\n"); 372 1.1 mrg printf ("x="); mpfr_dump (x); 373 1.1 mrg printf ("Expected "); mpfr_dump (y); 374 1.1 mrg printf ("Got "); mpfr_dump (z); 375 1.1 mrg exit (1); 376 1.1 mrg } 377 1.1 mrg if (inexact <= 0) 378 1.1 mrg { 379 1.1 mrg printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p); 380 1.1 mrg exit (1); 381 1.1 mrg } 382 1.1 mrg } 383 1.1 mrg 384 1.1 mrg mpfr_set_prec (x, 1000); 385 1.1 mrg mpfr_set_ui (x, 9, MPFR_RNDN); 386 1.1 mrg mpfr_set_prec (y, 10); 387 1.1 mrg inexact = test_sqrt (y, x, MPFR_RNDN); 388 1.1 mrg if (mpfr_cmp_ui (y, 3) || inexact != 0) 389 1.1 mrg { 390 1.1 mrg printf ("Error in sqrt(9:1000) for prec=10\n"); 391 1.1 mrg exit (1); 392 1.1 mrg } 393 1.1 mrg mpfr_set_prec (y, GMP_NUMB_BITS); 394 1.1 mrg mpfr_nextabove (x); 395 1.1 mrg inexact = test_sqrt (y, x, MPFR_RNDN); 396 1.1 mrg if (mpfr_cmp_ui (y, 3) || inexact >= 0) 397 1.1 mrg { 398 1.1 mrg printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS); 399 1.1 mrg exit (1); 400 1.1 mrg } 401 1.1 mrg mpfr_set_prec (x, 2 * GMP_NUMB_BITS); 402 1.1 mrg mpfr_set_prec (y, GMP_NUMB_BITS); 403 1.1 mrg mpfr_set_ui (y, 1, MPFR_RNDN); 404 1.1 mrg mpfr_nextabove (y); 405 1.1 mrg mpfr_set (x, y, MPFR_RNDN); 406 1.1 mrg inexact = test_sqrt (y, x, MPFR_RNDN); 407 1.1 mrg if (mpfr_cmp_ui (y, 1) || inexact >= 0) 408 1.1 mrg { 409 1.1 mrg printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS); 410 1.1 mrg mpfr_dump (y); 411 1.1 mrg exit (1); 412 1.1 mrg } 413 1.1 mrg 414 1.1 mrg mpfr_clear (x); 415 1.1 mrg mpfr_clear (y); 416 1.1 mrg mpfr_clear (z); 417 1.1 mrg } 418 1.1 mrg 419 1.1 mrg static void 420 1.1 mrg check_inexact (mpfr_prec_t p) 421 1.1 mrg { 422 1.1 mrg mpfr_t x, y, z; 423 1.1 mrg mpfr_rnd_t rnd; 424 1.1 mrg int inexact, sign; 425 1.1 mrg 426 1.1 mrg mpfr_init2 (x, p); 427 1.1 mrg mpfr_init2 (y, p); 428 1.1 mrg mpfr_init2 (z, 2*p); 429 1.1 mrg mpfr_urandomb (x, RANDS); 430 1.1.1.4 mrg rnd = RND_RAND_NO_RNDF (); 431 1.1 mrg inexact = test_sqrt (y, x, rnd); 432 1.1.1.6 mrg if (mpfr_sqr (z, y, rnd)) /* exact since prec(z) = 2*prec(y) */ 433 1.1 mrg { 434 1.1 mrg printf ("Error: multiplication should be exact\n"); 435 1.1 mrg exit (1); 436 1.1 mrg } 437 1.1 mrg mpfr_sub (z, z, x, rnd); /* exact also */ 438 1.1 mrg sign = mpfr_cmp_ui (z, 0); 439 1.1 mrg if (((inexact == 0) && (sign)) || 440 1.1 mrg ((inexact > 0) && (sign <= 0)) || 441 1.1 mrg ((inexact < 0) && (sign >= 0))) 442 1.1 mrg { 443 1.1.1.4 mrg printf ("Error with rnd=%s: wrong ternary value, expected %d, got %d\n", 444 1.1.1.4 mrg mpfr_print_rnd_mode (rnd), sign, inexact); 445 1.1 mrg printf ("x="); 446 1.1.1.4 mrg mpfr_dump (x); 447 1.1.1.4 mrg printf ("y="); 448 1.1.1.4 mrg mpfr_dump (y); 449 1.1 mrg exit (1); 450 1.1 mrg } 451 1.1 mrg mpfr_clear (x); 452 1.1 mrg mpfr_clear (y); 453 1.1 mrg mpfr_clear (z); 454 1.1 mrg } 455 1.1 mrg 456 1.1 mrg static void 457 1.1.1.2 mrg check_singular (void) 458 1.1 mrg { 459 1.1 mrg mpfr_t x, got; 460 1.1 mrg 461 1.1 mrg mpfr_init2 (x, 100L); 462 1.1 mrg mpfr_init2 (got, 100L); 463 1.1 mrg 464 1.1 mrg /* sqrt(NaN) == NaN */ 465 1.1 mrg MPFR_SET_NAN (x); 466 1.1 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 467 1.1 mrg MPFR_ASSERTN (mpfr_nan_p (got)); 468 1.1 mrg 469 1.1 mrg /* sqrt(-1) == NaN */ 470 1.1 mrg mpfr_set_si (x, -1L, MPFR_RNDZ); 471 1.1 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 472 1.1 mrg MPFR_ASSERTN (mpfr_nan_p (got)); 473 1.1 mrg 474 1.1 mrg /* sqrt(+inf) == +inf */ 475 1.1 mrg MPFR_SET_INF (x); 476 1.1 mrg MPFR_SET_POS (x); 477 1.1 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 478 1.1 mrg MPFR_ASSERTN (mpfr_inf_p (got)); 479 1.1 mrg 480 1.1 mrg /* sqrt(-inf) == NaN */ 481 1.1 mrg MPFR_SET_INF (x); 482 1.1 mrg MPFR_SET_NEG (x); 483 1.1 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 484 1.1 mrg MPFR_ASSERTN (mpfr_nan_p (got)); 485 1.1 mrg 486 1.1.1.2 mrg /* sqrt(+0) == +0 */ 487 1.1.1.2 mrg mpfr_set_si (x, 0L, MPFR_RNDZ); 488 1.1.1.2 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 489 1.1.1.2 mrg MPFR_ASSERTN (mpfr_number_p (got)); 490 1.1.1.2 mrg MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0); 491 1.1.1.2 mrg MPFR_ASSERTN (MPFR_IS_POS (got)); 492 1.1.1.2 mrg 493 1.1.1.2 mrg /* sqrt(-0) == -0 */ 494 1.1 mrg mpfr_set_si (x, 0L, MPFR_RNDZ); 495 1.1 mrg MPFR_SET_NEG (x); 496 1.1 mrg MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */ 497 1.1 mrg MPFR_ASSERTN (mpfr_number_p (got)); 498 1.1 mrg MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0); 499 1.1.1.2 mrg MPFR_ASSERTN (MPFR_IS_NEG (got)); 500 1.1 mrg 501 1.1 mrg mpfr_clear (x); 502 1.1 mrg mpfr_clear (got); 503 1.1 mrg } 504 1.1 mrg 505 1.1 mrg /* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up 506 1.1 mrg with s = 0 and s = 1 */ 507 1.1 mrg static void 508 1.1 mrg test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s) 509 1.1 mrg { 510 1.1 mrg mpfr_t x, y, z, t; 511 1.1 mrg 512 1.1 mrg mpfr_init2 (x, p); 513 1.1 mrg mpfr_init2 (y, p); 514 1.1 mrg mpfr_init2 (z, p); 515 1.1 mrg mpfr_init2 (t, p); 516 1.1 mrg 517 1.1 mrg mpfr_urandomb (x, RANDS); 518 1.1 mrg mpfr_mul (z, x, x, r); 519 1.1 mrg if (s) 520 1.1 mrg { 521 1.1 mrg mpfr_urandomb (y, RANDS); 522 1.1 mrg mpfr_mul (t, y, y, r); 523 1.1 mrg mpfr_add (z, z, t, r); 524 1.1 mrg } 525 1.1 mrg mpfr_sqrt (z, z, r); 526 1.1 mrg mpfr_div (z, x, z, r); 527 1.1 mrg /* Note: if both x and y are 0, z is NAN, but the test below will 528 1.1 mrg be false. So, everything is fine. */ 529 1.1 mrg if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0) 530 1.1 mrg { 531 1.1 mrg printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n", 532 1.1 mrg mpfr_print_rnd_mode (r)); 533 1.1 mrg printf ("x="); mpfr_dump (x); 534 1.1 mrg printf ("y="); mpfr_dump (y); 535 1.1 mrg printf ("got "); mpfr_dump (z); 536 1.1 mrg exit (1); 537 1.1 mrg } 538 1.1 mrg 539 1.1 mrg mpfr_clear (x); 540 1.1 mrg mpfr_clear (y); 541 1.1 mrg mpfr_clear (z); 542 1.1 mrg mpfr_clear (t); 543 1.1 mrg } 544 1.1 mrg 545 1.1 mrg /* check sqrt(x^2) = x */ 546 1.1 mrg static void 547 1.1 mrg test_property2 (mpfr_prec_t p, mpfr_rnd_t r) 548 1.1 mrg { 549 1.1 mrg mpfr_t x, y; 550 1.1 mrg 551 1.1 mrg mpfr_init2 (x, p); 552 1.1 mrg mpfr_init2 (y, p); 553 1.1 mrg 554 1.1 mrg mpfr_urandomb (x, RANDS); 555 1.1 mrg mpfr_mul (y, x, x, r); 556 1.1 mrg mpfr_sqrt (y, y, r); 557 1.1 mrg if (mpfr_cmp (y, x)) 558 1.1 mrg { 559 1.1 mrg printf ("Error, sqrt(x^2) = x does not hold for r=%s\n", 560 1.1 mrg mpfr_print_rnd_mode (r)); 561 1.1 mrg printf ("x="); mpfr_dump (x); 562 1.1 mrg printf ("got "); mpfr_dump (y); 563 1.1 mrg exit (1); 564 1.1 mrg } 565 1.1 mrg 566 1.1 mrg mpfr_clear (x); 567 1.1 mrg mpfr_clear (y); 568 1.1 mrg } 569 1.1 mrg 570 1.1.1.3 mrg /* Bug reported by Fredrik Johansson, occurring when: 571 1.1.1.3 mrg - the precision of the result is a multiple of the number of bits 572 1.1.1.3 mrg per word (GMP_NUMB_BITS), 573 1.1.1.3 mrg - the rounding mode is to nearest (MPFR_RNDN), 574 1.1.1.3 mrg - internally, the result has to be rounded up to a power of 2. 575 1.1.1.3 mrg */ 576 1.1.1.3 mrg static void 577 1.1.1.3 mrg bug20160120 (void) 578 1.1.1.3 mrg { 579 1.1.1.3 mrg mpfr_t x, y; 580 1.1.1.3 mrg 581 1.1.1.3 mrg mpfr_init2 (x, 4 * GMP_NUMB_BITS); 582 1.1.1.3 mrg mpfr_init2 (y, GMP_NUMB_BITS); 583 1.1.1.3 mrg 584 1.1.1.3 mrg mpfr_set_ui (x, 1, MPFR_RNDN); 585 1.1.1.3 mrg mpfr_nextbelow (x); 586 1.1.1.3 mrg mpfr_sqrt (y, x, MPFR_RNDN); 587 1.1.1.3 mrg MPFR_ASSERTN(mpfr_check (y)); 588 1.1.1.3 mrg MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); 589 1.1.1.3 mrg 590 1.1.1.3 mrg mpfr_set_prec (y, 2 * GMP_NUMB_BITS); 591 1.1.1.3 mrg mpfr_sqrt (y, x, MPFR_RNDN); 592 1.1.1.3 mrg MPFR_ASSERTN(mpfr_check (y)); 593 1.1.1.3 mrg MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0); 594 1.1.1.3 mrg 595 1.1.1.3 mrg mpfr_clear(x); 596 1.1.1.3 mrg mpfr_clear(y); 597 1.1.1.3 mrg } 598 1.1.1.3 mrg 599 1.1.1.4 mrg /* Bug in mpfr_sqrt2 when prec(u) = 2*GMP_NUMB_BITS and the exponent of u is 600 1.1.1.4 mrg odd: the last bit of u is lost. */ 601 1.1.1.4 mrg static void 602 1.1.1.4 mrg bug20160908 (void) 603 1.1.1.4 mrg { 604 1.1.1.4 mrg mpfr_t r, u; 605 1.1.1.4 mrg int n = GMP_NUMB_BITS, ret; 606 1.1.1.4 mrg 607 1.1.1.4 mrg mpfr_init2 (r, 2*n - 1); 608 1.1.1.4 mrg mpfr_init2 (u, 2 * n); 609 1.1.1.4 mrg mpfr_set_ui_2exp (u, 1, 2*n-2, MPFR_RNDN); /* u=2^(2n-2) with exp(u)=2n-1 */ 610 1.1.1.4 mrg mpfr_nextabove (u); 611 1.1.1.4 mrg /* now u = 2^(2n-2) + 1/2 */ 612 1.1.1.4 mrg ret = mpfr_sqrt (r, u, MPFR_RNDZ); 613 1.1.1.4 mrg MPFR_ASSERTN(ret == -1 && mpfr_cmp_ui_2exp (r, 1, n-1) == 0); 614 1.1.1.4 mrg mpfr_clear (r); 615 1.1.1.4 mrg mpfr_clear (u); 616 1.1.1.4 mrg } 617 1.1.1.4 mrg 618 1.1.1.4 mrg static void 619 1.1.1.4 mrg testall_rndf (mpfr_prec_t pmax) 620 1.1.1.4 mrg { 621 1.1.1.4 mrg mpfr_t a, b, d; 622 1.1.1.4 mrg mpfr_prec_t pa, pb; 623 1.1.1.4 mrg 624 1.1.1.4 mrg for (pa = MPFR_PREC_MIN; pa <= pmax; pa++) 625 1.1.1.4 mrg { 626 1.1.1.4 mrg mpfr_init2 (a, pa); 627 1.1.1.4 mrg mpfr_init2 (d, pa); 628 1.1.1.4 mrg for (pb = MPFR_PREC_MIN; pb <= pmax; pb++) 629 1.1.1.4 mrg { 630 1.1.1.4 mrg mpfr_init2 (b, pb); 631 1.1.1.4 mrg mpfr_set_ui (b, 1, MPFR_RNDN); 632 1.1.1.4 mrg while (mpfr_cmp_ui (b, 4) < 0) 633 1.1.1.4 mrg { 634 1.1.1.4 mrg mpfr_sqrt (a, b, MPFR_RNDF); 635 1.1.1.4 mrg mpfr_sqrt (d, b, MPFR_RNDD); 636 1.1.1.4 mrg if (!mpfr_equal_p (a, d)) 637 1.1.1.4 mrg { 638 1.1.1.4 mrg mpfr_sqrt (d, b, MPFR_RNDU); 639 1.1.1.4 mrg if (!mpfr_equal_p (a, d)) 640 1.1.1.4 mrg { 641 1.1.1.4 mrg printf ("Error: mpfr_sqrt(a,b,RNDF) does not " 642 1.1.1.4 mrg "match RNDD/RNDU\n"); 643 1.1.1.4 mrg printf ("b="); mpfr_dump (b); 644 1.1.1.4 mrg printf ("a="); mpfr_dump (a); 645 1.1.1.4 mrg exit (1); 646 1.1.1.4 mrg } 647 1.1.1.4 mrg } 648 1.1.1.4 mrg mpfr_nextabove (b); 649 1.1.1.4 mrg } 650 1.1.1.4 mrg mpfr_clear (b); 651 1.1.1.4 mrg } 652 1.1.1.4 mrg mpfr_clear (a); 653 1.1.1.4 mrg mpfr_clear (d); 654 1.1.1.4 mrg } 655 1.1.1.4 mrg } 656 1.1.1.4 mrg 657 1.1.1.4 mrg /* test the case prec = GMP_NUMB_BITS */ 658 1.1.1.4 mrg static void 659 1.1.1.4 mrg test_sqrt1n (void) 660 1.1.1.4 mrg { 661 1.1.1.4 mrg mpfr_t r, u; 662 1.1.1.4 mrg int inex; 663 1.1.1.4 mrg 664 1.1.1.5 mrg MPFR_ASSERTD(GMP_NUMB_BITS >= 8); /* so that 15^2 is exactly representable */ 665 1.1.1.5 mrg 666 1.1.1.4 mrg mpfr_init2 (r, GMP_NUMB_BITS); 667 1.1.1.4 mrg mpfr_init2 (u, GMP_NUMB_BITS); 668 1.1.1.4 mrg 669 1.1.1.5 mrg inex = mpfr_set_ui_2exp (u, 9 * 9, 2 * GMP_NUMB_BITS - 10, MPFR_RNDN); 670 1.1.1.5 mrg MPFR_ASSERTN(inex == 0); 671 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 672 1.1.1.5 mrg MPFR_ASSERTN(inex == 0); 673 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 9, GMP_NUMB_BITS - 5) == 0); 674 1.1.1.5 mrg 675 1.1.1.5 mrg inex = mpfr_set_ui_2exp (u, 15 * 15, 2 * GMP_NUMB_BITS - 10, MPFR_RNDN); 676 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 677 1.1.1.4 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 678 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 679 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 15, GMP_NUMB_BITS - 5) == 0); 680 1.1.1.4 mrg 681 1.1.1.4 mrg inex = mpfr_set_ui_2exp (u, 1, GMP_NUMB_BITS - 2, MPFR_RNDN); 682 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 683 1.1.1.4 mrg inex = mpfr_add_ui (u, u, 1, MPFR_RNDN); 684 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 685 1.1.1.5 mrg inex = mpfr_mul_2ui (u, u, GMP_NUMB_BITS, MPFR_RNDN); 686 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 687 1.1.1.4 mrg /* u = 2^(2*GMP_NUMB_BITS-2) + 2^GMP_NUMB_BITS, thus 688 1.1.1.4 mrg u = r^2 + 2^GMP_NUMB_BITS with r = 2^(GMP_NUMB_BITS-1). 689 1.1.1.4 mrg Should round to r+1 to nearest. */ 690 1.1.1.4 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 691 1.1.1.4 mrg MPFR_ASSERTN(inex > 0); 692 1.1.1.4 mrg inex = mpfr_sub_ui (r, r, 1, MPFR_RNDN); 693 1.1.1.4 mrg MPFR_ASSERTN(inex == 0); 694 1.1.1.4 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, GMP_NUMB_BITS - 1) == 0); 695 1.1.1.4 mrg 696 1.1.1.4 mrg mpfr_clear (r); 697 1.1.1.4 mrg mpfr_clear (u); 698 1.1.1.4 mrg } 699 1.1.1.4 mrg 700 1.1.1.5 mrg static void 701 1.1.1.5 mrg check_overflow (void) 702 1.1.1.5 mrg { 703 1.1.1.5 mrg mpfr_t r, u; 704 1.1.1.5 mrg mpfr_prec_t p; 705 1.1.1.5 mrg mpfr_exp_t emax; 706 1.1.1.5 mrg int inex; 707 1.1.1.5 mrg 708 1.1.1.5 mrg emax = mpfr_get_emax (); 709 1.1.1.5 mrg for (p = MPFR_PREC_MIN; p <= 1024; p++) 710 1.1.1.5 mrg { 711 1.1.1.5 mrg mpfr_init2 (r, p); 712 1.1.1.5 mrg mpfr_init2 (u, p); 713 1.1.1.5 mrg 714 1.1.1.6 mrg set_emax (-1); 715 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emax () - 1, MPFR_RNDN); 716 1.1.1.5 mrg mpfr_nextbelow (u); 717 1.1.1.5 mrg mpfr_mul_2ui (u, u, 1, MPFR_RNDN); 718 1.1.1.5 mrg /* now u = (1 - 2^(-p))*2^emax is the largest number < +Inf, 719 1.1.1.5 mrg it square root is near 0.707 and has exponent 0 > emax */ 720 1.1.1.5 mrg /* for RNDN, the result should be +Inf */ 721 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 722 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 723 1.1.1.5 mrg MPFR_ASSERTN(mpfr_inf_p (r) && mpfr_sgn (r) > 0); 724 1.1.1.5 mrg /* for RNDA, the result should be +Inf */ 725 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 726 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 727 1.1.1.5 mrg MPFR_ASSERTN(mpfr_inf_p (r) && mpfr_sgn (r) > 0); 728 1.1.1.5 mrg /* for RNDZ, the result should be u */ 729 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDZ); 730 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 731 1.1.1.5 mrg MPFR_ASSERTN(mpfr_equal_p (r, u)); 732 1.1.1.5 mrg 733 1.1.1.6 mrg set_emax (0); 734 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emax () - 1, MPFR_RNDN); 735 1.1.1.5 mrg mpfr_nextbelow (u); 736 1.1.1.5 mrg mpfr_mul_2ui (u, u, 1, MPFR_RNDN); 737 1.1.1.5 mrg /* u = 1-2^(-p), its square root is > u, and should thus give +Inf when 738 1.1.1.5 mrg rounding away */ 739 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 740 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 741 1.1.1.5 mrg MPFR_ASSERTN(mpfr_inf_p (r) && mpfr_sgn (r) > 0); 742 1.1.1.5 mrg 743 1.1.1.5 mrg mpfr_clear (r); 744 1.1.1.5 mrg mpfr_clear (u); 745 1.1.1.5 mrg } 746 1.1.1.6 mrg set_emax (emax); 747 1.1.1.5 mrg } 748 1.1.1.5 mrg 749 1.1.1.5 mrg static void 750 1.1.1.5 mrg check_underflow (void) 751 1.1.1.5 mrg { 752 1.1.1.5 mrg mpfr_t r, u; 753 1.1.1.5 mrg mpfr_prec_t p; 754 1.1.1.5 mrg mpfr_exp_t emin; 755 1.1.1.5 mrg int inex; 756 1.1.1.5 mrg 757 1.1.1.5 mrg emin = mpfr_get_emin (); 758 1.1.1.5 mrg for (p = MPFR_PREC_MIN; p <= 1024; p++) 759 1.1.1.5 mrg { 760 1.1.1.5 mrg mpfr_init2 (r, p); 761 1.1.1.5 mrg mpfr_init2 (u, p); 762 1.1.1.5 mrg 763 1.1.1.6 mrg set_emin (2); 764 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emin () - 1, MPFR_RNDN); /* u = 2 */ 765 1.1.1.5 mrg /* for RNDN, since sqrt(2) is closer from 2 than 0, the result is 2 */ 766 1.1.1.5 mrg mpfr_clear_flags (); 767 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 768 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 769 1.1.1.5 mrg MPFR_ASSERTN(mpfr_equal_p (r, u)); 770 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 771 1.1.1.5 mrg /* for RNDA, the result should be u, and there is underflow for p > 1, 772 1.1.1.5 mrg since for p=1 we have 1 < sqrt(2) < 2, but for p >= 2, sqrt(2) should 773 1.1.1.5 mrg be rounded to a number <= 1.5, which is representable */ 774 1.1.1.5 mrg mpfr_clear_flags (); 775 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 776 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 777 1.1.1.5 mrg MPFR_ASSERTN(mpfr_equal_p (r, u)); 778 1.1.1.5 mrg MPFR_ASSERTN((p == 1 && !mpfr_underflow_p ()) || 779 1.1.1.5 mrg (p != 1 && mpfr_underflow_p ())); 780 1.1.1.5 mrg /* for RNDZ, the result should be +0 */ 781 1.1.1.5 mrg mpfr_clear_flags (); 782 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDZ); 783 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 784 1.1.1.5 mrg MPFR_ASSERTN(mpfr_zero_p (r) && mpfr_signbit (r) == 0); 785 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 786 1.1.1.5 mrg 787 1.1.1.5 mrg /* generate an input u such that sqrt(u) < 0.5*2^emin but there is no 788 1.1.1.5 mrg underflow since sqrt(u) >= pred(0.5*2^emin), thus u >= 2^(2emin-2) */ 789 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, 2 * mpfr_get_emin () - 2, MPFR_RNDN); 790 1.1.1.5 mrg mpfr_clear_flags (); 791 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 792 1.1.1.5 mrg MPFR_ASSERTN(inex == 0); 793 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 794 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 795 1.1.1.5 mrg mpfr_clear_flags (); 796 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 797 1.1.1.5 mrg MPFR_ASSERTN(inex == 0); 798 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 799 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 800 1.1.1.5 mrg mpfr_clear_flags (); 801 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDZ); 802 1.1.1.5 mrg MPFR_ASSERTN(inex == 0); 803 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 804 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 805 1.1.1.5 mrg 806 1.1.1.5 mrg /* next number */ 807 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, 2 * mpfr_get_emin () - 2, MPFR_RNDN); 808 1.1.1.5 mrg mpfr_nextabove (u); 809 1.1.1.5 mrg mpfr_clear_flags (); 810 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 811 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 812 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 813 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 814 1.1.1.5 mrg mpfr_clear_flags (); 815 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 816 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 817 1.1.1.5 mrg mpfr_nextbelow (r); 818 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 819 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 820 1.1.1.5 mrg mpfr_clear_flags (); 821 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDZ); 822 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 823 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 824 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 825 1.1.1.5 mrg 826 1.1.1.5 mrg /* previous number */ 827 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, 2 * mpfr_get_emin () - 2, MPFR_RNDN); 828 1.1.1.5 mrg mpfr_nextbelow (u); 829 1.1.1.5 mrg mpfr_clear_flags (); 830 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 831 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 832 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 833 1.1.1.5 mrg /* since sqrt(u) is just below the middle between 0.5*2^emin and 834 1.1.1.5 mrg the previous number (with unbounded exponent range), there is 835 1.1.1.5 mrg underflow */ 836 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 837 1.1.1.5 mrg mpfr_clear_flags (); 838 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDA); 839 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 840 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 841 1.1.1.5 mrg MPFR_ASSERTN(!mpfr_underflow_p ()); 842 1.1.1.5 mrg mpfr_clear_flags (); 843 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDZ); 844 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 845 1.1.1.5 mrg mpfr_nextabove (r); 846 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, mpfr_get_emin () - 1) == 0); 847 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 848 1.1.1.5 mrg 849 1.1.1.6 mrg set_emin (3); 850 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emin () - 1, MPFR_RNDN); /* u = 4 */ 851 1.1.1.5 mrg /* sqrt(u) = 2 = 0.5^2^(emin-1) should be rounded to +0 */ 852 1.1.1.5 mrg mpfr_clear_flags (); 853 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 854 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 855 1.1.1.5 mrg MPFR_ASSERTN(mpfr_zero_p (r) && mpfr_signbit (r) == 0); 856 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 857 1.1.1.5 mrg 858 1.1.1.5 mrg /* next number */ 859 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emin () - 1, MPFR_RNDN); /* u = 4 */ 860 1.1.1.5 mrg mpfr_nextabove (u); 861 1.1.1.5 mrg /* sqrt(u) should be rounded to 4 */ 862 1.1.1.5 mrg mpfr_clear_flags (); 863 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 864 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 865 1.1.1.5 mrg MPFR_ASSERTN(mpfr_cmp_ui (r, 4) == 0); 866 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 867 1.1.1.5 mrg 868 1.1.1.6 mrg set_emin (4); 869 1.1.1.5 mrg mpfr_set_ui_2exp (u, 1, mpfr_get_emin () - 1, MPFR_RNDN); /* u = 8 */ 870 1.1.1.5 mrg /* sqrt(u) should be rounded to +0 */ 871 1.1.1.5 mrg mpfr_clear_flags (); 872 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 873 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 874 1.1.1.5 mrg MPFR_ASSERTN(mpfr_zero_p (r) && mpfr_signbit (r) == 0); 875 1.1.1.5 mrg MPFR_ASSERTN(mpfr_underflow_p ()); 876 1.1.1.5 mrg 877 1.1.1.5 mrg mpfr_clear (r); 878 1.1.1.5 mrg mpfr_clear (u); 879 1.1.1.5 mrg } 880 1.1.1.6 mrg set_emin (emin); 881 1.1.1.5 mrg } 882 1.1.1.5 mrg 883 1.1.1.5 mrg static void 884 1.1.1.5 mrg coverage (void) 885 1.1.1.5 mrg { 886 1.1.1.5 mrg mpfr_t r, t, u, v, w; 887 1.1.1.5 mrg mpfr_prec_t p; 888 1.1.1.5 mrg int inex; 889 1.1.1.5 mrg 890 1.1.1.5 mrg /* exercise even rule */ 891 1.1.1.5 mrg for (p = MPFR_PREC_MIN; p <= 1024; p++) 892 1.1.1.5 mrg { 893 1.1.1.5 mrg mpfr_init2 (r, p); 894 1.1.1.5 mrg mpfr_init2 (t, p + 1); 895 1.1.1.5 mrg mpfr_init2 (u, 2 * p + 2); 896 1.1.1.5 mrg mpfr_init2 (v, p); 897 1.1.1.5 mrg mpfr_init2 (w, p); 898 1.1.1.5 mrg do 899 1.1.1.5 mrg mpfr_urandomb (v, RANDS); 900 1.1.1.5 mrg while (mpfr_zero_p (v)); 901 1.1.1.5 mrg mpfr_set (w, v, MPFR_RNDN); 902 1.1.1.5 mrg mpfr_nextabove (w); /* w = nextabove(v) */ 903 1.1.1.5 mrg mpfr_set (t, v, MPFR_RNDN); 904 1.1.1.5 mrg mpfr_nextabove (t); 905 1.1.1.6 mrg mpfr_sqr (u, t, MPFR_RNDN); 906 1.1.1.5 mrg inex = mpfr_sqrt (r, u, MPFR_RNDN); 907 1.1.1.5 mrg if (mpfr_min_prec (v) < p) /* v is even */ 908 1.1.1.5 mrg { 909 1.1.1.5 mrg MPFR_ASSERTN(inex < 0); 910 1.1.1.5 mrg MPFR_ASSERTN(mpfr_equal_p (r, v)); 911 1.1.1.5 mrg } 912 1.1.1.5 mrg else /* v is odd */ 913 1.1.1.5 mrg { 914 1.1.1.5 mrg MPFR_ASSERTN(inex > 0); 915 1.1.1.5 mrg MPFR_ASSERTN(mpfr_equal_p (r, w)); 916 1.1.1.5 mrg } 917 1.1.1.5 mrg mpfr_clear (r); 918 1.1.1.5 mrg mpfr_clear (t); 919 1.1.1.5 mrg mpfr_clear (u); 920 1.1.1.5 mrg mpfr_clear (v); 921 1.1.1.5 mrg mpfr_clear (w); 922 1.1.1.5 mrg } 923 1.1.1.5 mrg } 924 1.1.1.5 mrg 925 1.1 mrg #define TEST_FUNCTION test_sqrt 926 1.1 mrg #define TEST_RANDOM_POS 8 927 1.1 mrg #include "tgeneric.c" 928 1.1 mrg 929 1.1 mrg int 930 1.1 mrg main (void) 931 1.1 mrg { 932 1.1 mrg mpfr_prec_t p; 933 1.1 mrg int k; 934 1.1 mrg 935 1.1 mrg tests_start_mpfr (); 936 1.1 mrg 937 1.1.1.5 mrg coverage (); 938 1.1.1.5 mrg check_underflow (); 939 1.1.1.5 mrg check_overflow (); 940 1.1.1.4 mrg testall_rndf (16); 941 1.1 mrg for (p = MPFR_PREC_MIN; p <= 128; p++) 942 1.1 mrg { 943 1.1 mrg test_property1 (p, MPFR_RNDN, 0); 944 1.1 mrg test_property1 (p, MPFR_RNDU, 0); 945 1.1 mrg test_property1 (p, MPFR_RNDA, 0); 946 1.1 mrg test_property1 (p, MPFR_RNDN, 1); 947 1.1 mrg test_property1 (p, MPFR_RNDU, 1); 948 1.1 mrg test_property1 (p, MPFR_RNDA, 1); 949 1.1 mrg test_property2 (p, MPFR_RNDN); 950 1.1 mrg } 951 1.1 mrg 952 1.1 mrg check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637"); 953 1.1 mrg special (); 954 1.1.1.2 mrg check_singular (); 955 1.1 mrg 956 1.1 mrg for (p=2; p<200; p++) 957 1.1 mrg for (k=0; k<200; k++) 958 1.1 mrg check_inexact (p); 959 1.1 mrg check_float(); 960 1.1 mrg 961 1.1 mrg check3 ("-0.0", MPFR_RNDN, "0.0"); 962 1.1 mrg check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13"); 963 1.1 mrg check4 ("1.0", MPFR_RNDN, "1"); 964 1.1 mrg check4 ("1.0", MPFR_RNDZ, "1"); 965 1.1 mrg check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4"); 966 1.1 mrg check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4"); 967 1.1 mrg check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6"); 968 1.1 mrg check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7"); 969 1.1 mrg /* the following examples are bugs in Cygnus compiler/system, found by 970 1.1 mrg Fabrice Rouillier while porting mpfr to Windows */ 971 1.1 mrg check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56"); 972 1.1 mrg check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13"); 973 1.1 mrg check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1"); 974 1.1 mrg check4 ("1.00000000000000022204", MPFR_RNDN, "1"); 975 1.1 mrg /* the following examples come from the paper "Number-theoretic Test 976 1.1 mrg Generation for Directed Rounding" from Michael Parks, Table 4 */ 977 1.1 mrg 978 1.1 mrg check4 ("78652858805036375191418371571712.0", MPFR_RNDN, 979 1.1 mrg "1.f81fc40f32063@13"); 980 1.1 mrg check4 ("38510074998589467860312736661504.0", MPFR_RNDN, 981 1.1 mrg "1.60c012a92fc65@13"); 982 1.1 mrg check4 ("35318779685413012908190921129984.0", MPFR_RNDN, 983 1.1 mrg "1.51d17526c7161@13"); 984 1.1 mrg check4 ("26729022595358440976973142425600.0", MPFR_RNDN, 985 1.1 mrg "1.25e19302f7e51@13"); 986 1.1 mrg check4 ("22696567866564242819241453027328.0", MPFR_RNDN, 987 1.1 mrg "1.0ecea7dd2ec3d@13"); 988 1.1 mrg check4 ("22696888073761729132924856434688.0", MPFR_RNDN, 989 1.1 mrg "1.0ecf250e8e921@13"); 990 1.1 mrg check4 ("36055652513981905145251657416704.0", MPFR_RNDN, 991 1.1 mrg "1.5552f3eedcf33@13"); 992 1.1 mrg check4 ("30189856268896404997497182748672.0", MPFR_RNDN, 993 1.1 mrg "1.3853ee10c9c99@13"); 994 1.1 mrg check4 ("36075288240584711210898775080960.0", MPFR_RNDN, 995 1.1 mrg "1.556abe212b56f@13"); 996 1.1 mrg check4 ("72154663483843080704304789585920.0", MPFR_RNDN, 997 1.1 mrg "1.e2d9a51977e6e@13"); 998 1.1 mrg 999 1.1 mrg check4 ("78652858805036375191418371571712.0", MPFR_RNDZ, 1000 1.1 mrg "1.f81fc40f32062@13"); 1001 1.1 mrg check4 ("38510074998589467860312736661504.0", MPFR_RNDZ, 1002 1.1 mrg "1.60c012a92fc64@13"); 1003 1.1 mrg check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13"); 1004 1.1 mrg check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13"); 1005 1.1 mrg check4 ("22696567866564242819241453027328.0", MPFR_RNDZ, 1006 1.1 mrg "1.0ecea7dd2ec3c@13"); 1007 1.1 mrg check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13"); 1008 1.1 mrg check4 ("36055652513981905145251657416704.0", MPFR_RNDZ, 1009 1.1 mrg "1.5552f3eedcf32@13"); 1010 1.1 mrg check4 ("30189856268896404997497182748672.0", MPFR_RNDZ, 1011 1.1 mrg "1.3853ee10c9c98@13"); 1012 1.1 mrg check4 ("36075288240584711210898775080960.0", MPFR_RNDZ, 1013 1.1 mrg "1.556abe212b56e@13"); 1014 1.1 mrg check4 ("72154663483843080704304789585920.0", MPFR_RNDZ, 1015 1.1 mrg "1.e2d9a51977e6d@13"); 1016 1.1 mrg 1017 1.1 mrg check4 ("78652858805036375191418371571712.0", MPFR_RNDU, 1018 1.1 mrg "1.f81fc40f32063@13"); 1019 1.1 mrg check4 ("38510074998589467860312736661504.0", MPFR_RNDU, 1020 1.1 mrg "1.60c012a92fc65@13"); 1021 1.1 mrg check4 ("35318779685413012908190921129984.0", MPFR_RNDU, 1022 1.1 mrg "1.51d17526c7161@13"); 1023 1.1 mrg check4 ("26729022595358440976973142425600.0", MPFR_RNDU, 1024 1.1 mrg "1.25e19302f7e51@13"); 1025 1.1 mrg check4 ("22696567866564242819241453027328.0", MPFR_RNDU, 1026 1.1 mrg "1.0ecea7dd2ec3d@13"); 1027 1.1 mrg check4 ("22696888073761729132924856434688.0", MPFR_RNDU, 1028 1.1 mrg "1.0ecf250e8e921@13"); 1029 1.1 mrg check4 ("36055652513981905145251657416704.0", MPFR_RNDU, 1030 1.1 mrg "1.5552f3eedcf33@13"); 1031 1.1 mrg check4 ("30189856268896404997497182748672.0", MPFR_RNDU, 1032 1.1 mrg "1.3853ee10c9c99@13"); 1033 1.1 mrg check4 ("36075288240584711210898775080960.0", MPFR_RNDU, 1034 1.1 mrg "1.556abe212b56f@13"); 1035 1.1 mrg check4 ("72154663483843080704304789585920.0", MPFR_RNDU, 1036 1.1 mrg "1.e2d9a51977e6e@13"); 1037 1.1 mrg 1038 1.1 mrg check4 ("78652858805036375191418371571712.0", MPFR_RNDD, 1039 1.1 mrg "1.f81fc40f32062@13"); 1040 1.1 mrg check4 ("38510074998589467860312736661504.0", MPFR_RNDD, 1041 1.1 mrg "1.60c012a92fc64@13"); 1042 1.1 mrg check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13"); 1043 1.1 mrg check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13"); 1044 1.1 mrg check4 ("22696567866564242819241453027328.0", MPFR_RNDD, 1045 1.1 mrg "1.0ecea7dd2ec3c@13"); 1046 1.1 mrg check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13"); 1047 1.1 mrg check4 ("36055652513981905145251657416704.0", MPFR_RNDD, 1048 1.1 mrg "1.5552f3eedcf32@13"); 1049 1.1 mrg check4 ("30189856268896404997497182748672.0", MPFR_RNDD, 1050 1.1 mrg "1.3853ee10c9c98@13"); 1051 1.1 mrg check4 ("36075288240584711210898775080960.0", MPFR_RNDD, 1052 1.1 mrg "1.556abe212b56e@13"); 1053 1.1 mrg check4 ("72154663483843080704304789585920.0", MPFR_RNDD, 1054 1.1 mrg "1.e2d9a51977e6d@13"); 1055 1.1 mrg 1056 1.1.1.6 mrg /* check that rounding away is just rounding toward positive infinity */ 1057 1.1 mrg check4 ("72154663483843080704304789585920.0", MPFR_RNDA, 1058 1.1 mrg "1.e2d9a51977e6e@13"); 1059 1.1 mrg 1060 1.1.1.4 mrg test_generic (MPFR_PREC_MIN, 300, 15); 1061 1.1 mrg data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt"); 1062 1.1.1.5 mrg bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 0, -256, 255, 4, 128, 80, 50); 1063 1.1 mrg 1064 1.1.1.3 mrg bug20160120 (); 1065 1.1.1.4 mrg bug20160908 (); 1066 1.1.1.4 mrg test_sqrt1n (); 1067 1.1.1.3 mrg 1068 1.1 mrg tests_end_mpfr (); 1069 1.1 mrg return 0; 1070 1.1 mrg } 1071