tsqrt.c revision 1.1.1.3.4.1 1 /* Test file for mpfr_sqrt.
2
3 Copyright 1999, 2001-2018 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 "mpfr-test.h"
24
25 #ifdef CHECK_EXTERNAL
26 static int
27 test_sqrt (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
28 {
29 int res;
30 int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b);
31 if (ok)
32 {
33 mpfr_print_raw (b);
34 }
35 res = mpfr_sqrt (a, b, rnd_mode);
36 if (ok)
37 {
38 printf (" ");
39 mpfr_print_raw (a);
40 printf ("\n");
41 }
42 return res;
43 }
44 #else
45 #define test_sqrt mpfr_sqrt
46 #endif
47
48 static void
49 check3 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
50 {
51 mpfr_t q;
52
53 mpfr_init2 (q, 53);
54 mpfr_set_str1 (q, as);
55 test_sqrt (q, q, rnd_mode);
56 if (mpfr_cmp_str1 (q, qs) )
57 {
58 printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
59 as, mpfr_print_rnd_mode (rnd_mode));
60 printf ("expected sqrt is %s, got ",qs);
61 mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
62 putchar ('\n');
63 exit (1);
64 }
65 mpfr_clear (q);
66 }
67
68 static void
69 check4 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
70 {
71 mpfr_t q;
72
73 mpfr_init2 (q, 53);
74 mpfr_set_str1 (q, as);
75 test_sqrt (q, q, rnd_mode);
76 if (mpfr_cmp_str (q, qs, 16, MPFR_RNDN))
77 {
78 printf ("mpfr_sqrt failed for a=%s, rnd_mode=%s\n",
79 as, mpfr_print_rnd_mode (rnd_mode));
80 printf ("expected %s\ngot ", qs);
81 mpfr_out_str (stdout, 16, 0, q, MPFR_RNDN);
82 printf ("\n");
83 mpfr_clear (q);
84 exit (1);
85 }
86 mpfr_clear (q);
87 }
88
89 static void
90 check24 (const char *as, mpfr_rnd_t rnd_mode, const char *qs)
91 {
92 mpfr_t q;
93
94 mpfr_init2 (q, 24);
95 mpfr_set_str1 (q, as);
96 test_sqrt (q, q, rnd_mode);
97 if (mpfr_cmp_str1 (q, qs))
98 {
99 printf ("mpfr_sqrt failed for a=%s, prec=24, rnd_mode=%s\n",
100 as, mpfr_print_rnd_mode(rnd_mode));
101 printf ("expected sqrt is %s, got ",qs);
102 mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
103 printf ("\n");
104 exit (1);
105 }
106 mpfr_clear (q);
107 }
108
109 static void
110 check_diverse (const char *as, mpfr_prec_t p, const char *qs)
111 {
112 mpfr_t q;
113
114 mpfr_init2 (q, p);
115 mpfr_set_str1 (q, as);
116 test_sqrt (q, q, MPFR_RNDN);
117 if (mpfr_cmp_str1 (q, qs))
118 {
119 printf ("mpfr_sqrt failed for a=%s, prec=%lu, rnd_mode=%s\n",
120 as, (unsigned long) p, mpfr_print_rnd_mode (MPFR_RNDN));
121 printf ("expected sqrt is %s, got ", qs);
122 mpfr_out_str (stdout, 10, 0, q, MPFR_RNDN);
123 printf ("\n");
124 exit (1);
125 }
126 mpfr_clear (q);
127 }
128
129 /* the following examples come from the paper "Number-theoretic Test
130 Generation for Directed Rounding" from Michael Parks, Table 3 */
131 static void
132 check_float (void)
133 {
134 check24("70368760954880.0", MPFR_RNDN, "8.388609e6");
135 check24("281474943156224.0", MPFR_RNDN, "1.6777215e7");
136 check24("70368777732096.0", MPFR_RNDN, "8.388610e6");
137 check24("281474909601792.0", MPFR_RNDN, "1.6777214e7");
138 check24("100216216748032.0", MPFR_RNDN, "1.0010805e7");
139 check24("120137273311232.0", MPFR_RNDN, "1.0960715e7");
140 check24("229674600890368.0", MPFR_RNDN, "1.5155019e7");
141 check24("70368794509312.0", MPFR_RNDN, "8.388611e6");
142 check24("281474876047360.0", MPFR_RNDN, "1.6777213e7");
143 check24("91214552498176.0", MPFR_RNDN, "9.550631e6");
144
145 check24("70368760954880.0", MPFR_RNDZ, "8.388608e6");
146 check24("281474943156224.0", MPFR_RNDZ, "1.6777214e7");
147 check24("70368777732096.0", MPFR_RNDZ, "8.388609e6");
148 check24("281474909601792.0", MPFR_RNDZ, "1.6777213e7");
149 check24("100216216748032.0", MPFR_RNDZ, "1.0010805e7");
150 check24("120137273311232.0", MPFR_RNDZ, "1.0960715e7");
151 check24("229674600890368.0", MPFR_RNDZ, "1.5155019e7");
152 check24("70368794509312.0", MPFR_RNDZ, "8.38861e6");
153 check24("281474876047360.0", MPFR_RNDZ, "1.6777212e7");
154 check24("91214552498176.0", MPFR_RNDZ, "9.550631e6");
155
156 check24("70368760954880.0", MPFR_RNDU, "8.388609e6");
157 check24("281474943156224.0",MPFR_RNDU, "1.6777215e7");
158 check24("70368777732096.0", MPFR_RNDU, "8.388610e6");
159 check24("281474909601792.0", MPFR_RNDU, "1.6777214e7");
160 check24("100216216748032.0", MPFR_RNDU, "1.0010806e7");
161 check24("120137273311232.0", MPFR_RNDU, "1.0960716e7");
162 check24("229674600890368.0", MPFR_RNDU, "1.515502e7");
163 check24("70368794509312.0", MPFR_RNDU, "8.388611e6");
164 check24("281474876047360.0", MPFR_RNDU, "1.6777213e7");
165 check24("91214552498176.0", MPFR_RNDU, "9.550632e6");
166
167 check24("70368760954880.0", MPFR_RNDD, "8.388608e6");
168 check24("281474943156224.0", MPFR_RNDD, "1.6777214e7");
169 check24("70368777732096.0", MPFR_RNDD, "8.388609e6");
170 check24("281474909601792.0", MPFR_RNDD, "1.6777213e7");
171 check24("100216216748032.0", MPFR_RNDD, "1.0010805e7");
172 check24("120137273311232.0", MPFR_RNDD, "1.0960715e7");
173 check24("229674600890368.0", MPFR_RNDD, "1.5155019e7");
174 check24("70368794509312.0", MPFR_RNDD, "8.38861e6");
175 check24("281474876047360.0", MPFR_RNDD, "1.6777212e7");
176 check24("91214552498176.0", MPFR_RNDD, "9.550631e6");
177
178 /* check that rounding away is just rounding toward plus infinity */
179 check24("91214552498176.0", MPFR_RNDA, "9.550632e6");
180 }
181
182 static void
183 special (void)
184 {
185 mpfr_t x, y, z;
186 int inexact;
187 mpfr_prec_t p;
188
189 mpfr_init (x);
190 mpfr_init (y);
191 mpfr_init (z);
192
193 mpfr_set_prec (x, 64);
194 mpfr_set_str_binary (x, "1010000010100011011001010101010010001100001101011101110001011001E-1");
195 mpfr_set_prec (y, 32);
196 test_sqrt (y, x, MPFR_RNDN);
197 if (mpfr_cmp_ui (y, 2405743844UL))
198 {
199 printf ("Error for n^2+n+1/2 with n=2405743843\n");
200 exit (1);
201 }
202
203 mpfr_set_prec (x, 65);
204 mpfr_set_str_binary (x, "10100000101000110110010101010100100011000011010111011100010110001E-2");
205 mpfr_set_prec (y, 32);
206 test_sqrt (y, x, MPFR_RNDN);
207 if (mpfr_cmp_ui (y, 2405743844UL))
208 {
209 printf ("Error for n^2+n+1/4 with n=2405743843\n");
210 mpfr_dump (y);
211 exit (1);
212 }
213
214 mpfr_set_prec (x, 66);
215 mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100011E-3");
216 mpfr_set_prec (y, 32);
217 test_sqrt (y, x, MPFR_RNDN);
218 if (mpfr_cmp_ui (y, 2405743844UL))
219 {
220 printf ("Error for n^2+n+1/4+1/8 with n=2405743843\n");
221 mpfr_dump (y);
222 exit (1);
223 }
224
225 mpfr_set_prec (x, 66);
226 mpfr_set_str_binary (x, "101000001010001101100101010101001000110000110101110111000101100001E-3");
227 mpfr_set_prec (y, 32);
228 test_sqrt (y, x, MPFR_RNDN);
229 if (mpfr_cmp_ui (y, 2405743843UL))
230 {
231 printf ("Error for n^2+n+1/8 with n=2405743843\n");
232 mpfr_dump (y);
233 exit (1);
234 }
235
236 mpfr_set_prec (x, 27);
237 mpfr_set_str_binary (x, "0.110100111010101000010001011");
238 if ((inexact = test_sqrt (x, x, MPFR_RNDZ)) >= 0)
239 {
240 printf ("Wrong inexact flag: expected -1, got %d\n", inexact);
241 exit (1);
242 }
243
244 mpfr_set_prec (x, 2);
245 for (p=2; p<1000; p++)
246 {
247 mpfr_set_prec (z, p);
248 mpfr_set_ui (z, 1, MPFR_RNDN);
249 mpfr_nexttoinf (z);
250 test_sqrt (x, z, MPFR_RNDU);
251 if (mpfr_cmp_ui_2exp(x, 3, -1))
252 {
253 printf ("Error: sqrt(1+ulp(1), up) should give 1.5 (prec=%u)\n",
254 (unsigned int) p);
255 printf ("got "); mpfr_dump (x);
256 exit (1);
257 }
258 }
259
260 /* check inexact flag */
261 mpfr_set_prec (x, 5);
262 mpfr_set_str_binary (x, "1.1001E-2");
263 if ((inexact = test_sqrt (x, x, MPFR_RNDN)))
264 {
265 printf ("Wrong inexact flag: expected 0, got %d\n", inexact);
266 exit (1);
267 }
268
269 mpfr_set_prec (x, 2);
270 mpfr_set_prec (z, 2);
271
272 /* checks the sign is correctly set */
273 mpfr_set_si (x, 1, MPFR_RNDN);
274 mpfr_set_si (z, -1, MPFR_RNDN);
275 test_sqrt (z, x, MPFR_RNDN);
276 if (mpfr_cmp_ui (z, 0) < 0)
277 {
278 printf ("Error: square root of 1 gives ");
279 mpfr_dump (z);
280 exit (1);
281 }
282
283 mpfr_set_prec (x, 192);
284 mpfr_set_prec (z, 160);
285 mpfr_set_str_binary (z, "0.1011010100000100100100100110011001011100100100000011000111011001011101101101110000110100001000100001100001011000E1");
286 mpfr_set_prec (x, 160);
287 test_sqrt(x, z, MPFR_RNDN);
288 test_sqrt(z, x, MPFR_RNDN);
289
290 mpfr_set_prec (x, 53);
291 mpfr_set_str (x, "8093416094703476.0", 10, MPFR_RNDN);
292 mpfr_div_2exp (x, x, 1075, MPFR_RNDN);
293 test_sqrt (x, x, MPFR_RNDN);
294 mpfr_set_str (z, "1e55596835b5ef@-141", 16, MPFR_RNDN);
295 if (mpfr_cmp (x, z))
296 {
297 printf ("Error: square root of 8093416094703476*2^(-1075)\n");
298 printf ("expected "); mpfr_dump (z);
299 printf ("got "); mpfr_dump (x);
300 exit (1);
301 }
302
303 mpfr_set_prec (x, 33);
304 mpfr_set_str_binary (x, "0.111011011011110001100111111001000e-10");
305 mpfr_set_prec (z, 157);
306 inexact = test_sqrt (z, x, MPFR_RNDN);
307 mpfr_set_prec (x, 157);
308 mpfr_set_str_binary (x, "0.11110110101100101111001011100011100011100001101010111011010000100111011000111110100001001011110011111100101110010110010110011001011011010110010000011001101E-5");
309 if (mpfr_cmp (x, z))
310 {
311 printf ("Error: square root (1)\n");
312 exit (1);
313 }
314 if (inexact <= 0)
315 {
316 printf ("Error: wrong inexact flag (1)\n");
317 exit (1);
318 }
319
320 /* case prec(result) << prec(input) */
321 mpfr_set_prec (z, 2);
322 for (p = mpfr_get_prec (z); p < 1000; p++)
323 {
324 mpfr_set_prec (x, p);
325 mpfr_set_ui (x, 1, MPFR_RNDN);
326 mpfr_nextabove (x);
327 /* 1.0 < x <= 1.5 thus 1 < sqrt(x) <= 1.23 */
328 inexact = test_sqrt (z, x, MPFR_RNDN);
329 MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
330 inexact = test_sqrt (z, x, MPFR_RNDZ);
331 MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
332 inexact = test_sqrt (z, x, MPFR_RNDU);
333 MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
334 inexact = test_sqrt (z, x, MPFR_RNDD);
335 MPFR_ASSERTN(inexact < 0 && mpfr_cmp_ui (z, 1) == 0);
336 inexact = test_sqrt (z, x, MPFR_RNDA);
337 MPFR_ASSERTN(inexact > 0 && mpfr_cmp_ui_2exp (z, 3, -1) == 0);
338 }
339
340 /* corner case rw = 0 in rounding to nearest */
341 mpfr_set_prec (z, GMP_NUMB_BITS - 1);
342 mpfr_set_prec (y, GMP_NUMB_BITS - 1);
343 mpfr_set_ui (y, 1, MPFR_RNDN);
344 mpfr_mul_2exp (y, y, GMP_NUMB_BITS - 1, MPFR_RNDN);
345 mpfr_nextabove (y);
346 for (p = 2 * GMP_NUMB_BITS - 1; p <= 1000; p++)
347 {
348 mpfr_set_prec (x, p);
349 mpfr_set_ui (x, 1, MPFR_RNDN);
350 mpfr_set_exp (x, GMP_NUMB_BITS);
351 mpfr_add_ui (x, x, 1, MPFR_RNDN);
352 /* now x = 2^(GMP_NUMB_BITS - 1) + 1 (GMP_NUMB_BITS bits) */
353 inexact = mpfr_mul (x, x, x, MPFR_RNDN);
354 MPFR_ASSERTN (inexact == 0); /* exact */
355 inexact = test_sqrt (z, x, MPFR_RNDN);
356 /* even rule: z should be 2^(GMP_NUMB_BITS - 1) */
357 MPFR_ASSERTN (inexact < 0);
358 inexact = mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1);
359 MPFR_ASSERTN (inexact == 0);
360 mpfr_nextbelow (x);
361 /* now x is just below [2^(GMP_NUMB_BITS - 1) + 1]^2 */
362 inexact = test_sqrt (z, x, MPFR_RNDN);
363 MPFR_ASSERTN(inexact < 0 &&
364 mpfr_cmp_ui_2exp (z, 1, GMP_NUMB_BITS - 1) == 0);
365 mpfr_nextabove (x);
366 mpfr_nextabove (x);
367 /* now x is just above [2^(GMP_NUMB_BITS - 1) + 1]^2 */
368 inexact = test_sqrt (z, x, MPFR_RNDN);
369 if (mpfr_cmp (z, y))
370 {
371 printf ("Error for sqrt(x) in rounding to nearest\n");
372 printf ("x="); mpfr_dump (x);
373 printf ("Expected "); mpfr_dump (y);
374 printf ("Got "); mpfr_dump (z);
375 exit (1);
376 }
377 if (inexact <= 0)
378 {
379 printf ("Wrong inexact flag in corner case for p = %lu\n", (unsigned long) p);
380 exit (1);
381 }
382 }
383
384 mpfr_set_prec (x, 1000);
385 mpfr_set_ui (x, 9, MPFR_RNDN);
386 mpfr_set_prec (y, 10);
387 inexact = test_sqrt (y, x, MPFR_RNDN);
388 if (mpfr_cmp_ui (y, 3) || inexact != 0)
389 {
390 printf ("Error in sqrt(9:1000) for prec=10\n");
391 exit (1);
392 }
393 mpfr_set_prec (y, GMP_NUMB_BITS);
394 mpfr_nextabove (x);
395 inexact = test_sqrt (y, x, MPFR_RNDN);
396 if (mpfr_cmp_ui (y, 3) || inexact >= 0)
397 {
398 printf ("Error in sqrt(9:1000) for prec=%d\n", (int) GMP_NUMB_BITS);
399 exit (1);
400 }
401 mpfr_set_prec (x, 2 * GMP_NUMB_BITS);
402 mpfr_set_prec (y, GMP_NUMB_BITS);
403 mpfr_set_ui (y, 1, MPFR_RNDN);
404 mpfr_nextabove (y);
405 mpfr_set (x, y, MPFR_RNDN);
406 inexact = test_sqrt (y, x, MPFR_RNDN);
407 if (mpfr_cmp_ui (y, 1) || inexact >= 0)
408 {
409 printf ("Error in sqrt(1) for prec=%d\n", (int) GMP_NUMB_BITS);
410 mpfr_dump (y);
411 exit (1);
412 }
413
414 mpfr_clear (x);
415 mpfr_clear (y);
416 mpfr_clear (z);
417 }
418
419 static void
420 check_inexact (mpfr_prec_t p)
421 {
422 mpfr_t x, y, z;
423 mpfr_rnd_t rnd;
424 int inexact, sign;
425
426 mpfr_init2 (x, p);
427 mpfr_init2 (y, p);
428 mpfr_init2 (z, 2*p);
429 mpfr_urandomb (x, RANDS);
430 rnd = RND_RAND_NO_RNDF ();
431 inexact = test_sqrt (y, x, rnd);
432 if (mpfr_mul (z, y, y, rnd)) /* exact since prec(z) = 2*prec(y) */
433 {
434 printf ("Error: multiplication should be exact\n");
435 exit (1);
436 }
437 mpfr_sub (z, z, x, rnd); /* exact also */
438 sign = mpfr_cmp_ui (z, 0);
439 if (((inexact == 0) && (sign)) ||
440 ((inexact > 0) && (sign <= 0)) ||
441 ((inexact < 0) && (sign >= 0)))
442 {
443 printf ("Error with rnd=%s: wrong ternary value, expected %d, got %d\n",
444 mpfr_print_rnd_mode (rnd), sign, inexact);
445 printf ("x=");
446 mpfr_dump (x);
447 printf ("y=");
448 mpfr_dump (y);
449 exit (1);
450 }
451 mpfr_clear (x);
452 mpfr_clear (y);
453 mpfr_clear (z);
454 }
455
456 static void
457 check_singular (void)
458 {
459 mpfr_t x, got;
460
461 mpfr_init2 (x, 100L);
462 mpfr_init2 (got, 100L);
463
464 /* sqrt(NaN) == NaN */
465 MPFR_SET_NAN (x);
466 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
467 MPFR_ASSERTN (mpfr_nan_p (got));
468
469 /* sqrt(-1) == NaN */
470 mpfr_set_si (x, -1L, MPFR_RNDZ);
471 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
472 MPFR_ASSERTN (mpfr_nan_p (got));
473
474 /* sqrt(+inf) == +inf */
475 MPFR_SET_INF (x);
476 MPFR_SET_POS (x);
477 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
478 MPFR_ASSERTN (mpfr_inf_p (got));
479
480 /* sqrt(-inf) == NaN */
481 MPFR_SET_INF (x);
482 MPFR_SET_NEG (x);
483 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
484 MPFR_ASSERTN (mpfr_nan_p (got));
485
486 /* sqrt(+0) == +0 */
487 mpfr_set_si (x, 0L, MPFR_RNDZ);
488 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
489 MPFR_ASSERTN (mpfr_number_p (got));
490 MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
491 MPFR_ASSERTN (MPFR_IS_POS (got));
492
493 /* sqrt(-0) == -0 */
494 mpfr_set_si (x, 0L, MPFR_RNDZ);
495 MPFR_SET_NEG (x);
496 MPFR_ASSERTN (test_sqrt (got, x, MPFR_RNDZ) == 0); /* exact */
497 MPFR_ASSERTN (mpfr_number_p (got));
498 MPFR_ASSERTN (mpfr_cmp_ui (got, 0L) == 0);
499 MPFR_ASSERTN (MPFR_IS_NEG (got));
500
501 mpfr_clear (x);
502 mpfr_clear (got);
503 }
504
505 /* check that -1 <= x/sqrt(x^2+s*y^2) <= 1 for rounding to nearest or up
506 with s = 0 and s = 1 */
507 static void
508 test_property1 (mpfr_prec_t p, mpfr_rnd_t r, int s)
509 {
510 mpfr_t x, y, z, t;
511
512 mpfr_init2 (x, p);
513 mpfr_init2 (y, p);
514 mpfr_init2 (z, p);
515 mpfr_init2 (t, p);
516
517 mpfr_urandomb (x, RANDS);
518 mpfr_mul (z, x, x, r);
519 if (s)
520 {
521 mpfr_urandomb (y, RANDS);
522 mpfr_mul (t, y, y, r);
523 mpfr_add (z, z, t, r);
524 }
525 mpfr_sqrt (z, z, r);
526 mpfr_div (z, x, z, r);
527 /* Note: if both x and y are 0, z is NAN, but the test below will
528 be false. So, everything is fine. */
529 if (mpfr_cmp_si (z, -1) < 0 || mpfr_cmp_ui (z, 1) > 0)
530 {
531 printf ("Error, -1 <= x/sqrt(x^2+y^2) <= 1 does not hold for r=%s\n",
532 mpfr_print_rnd_mode (r));
533 printf ("x="); mpfr_dump (x);
534 printf ("y="); mpfr_dump (y);
535 printf ("got "); mpfr_dump (z);
536 exit (1);
537 }
538
539 mpfr_clear (x);
540 mpfr_clear (y);
541 mpfr_clear (z);
542 mpfr_clear (t);
543 }
544
545 /* check sqrt(x^2) = x */
546 static void
547 test_property2 (mpfr_prec_t p, mpfr_rnd_t r)
548 {
549 mpfr_t x, y;
550
551 mpfr_init2 (x, p);
552 mpfr_init2 (y, p);
553
554 mpfr_urandomb (x, RANDS);
555 mpfr_mul (y, x, x, r);
556 mpfr_sqrt (y, y, r);
557 if (mpfr_cmp (y, x))
558 {
559 printf ("Error, sqrt(x^2) = x does not hold for r=%s\n",
560 mpfr_print_rnd_mode (r));
561 printf ("x="); mpfr_dump (x);
562 printf ("got "); mpfr_dump (y);
563 exit (1);
564 }
565
566 mpfr_clear (x);
567 mpfr_clear (y);
568 }
569
570 /* Bug reported by Fredrik Johansson, occurring when:
571 - the precision of the result is a multiple of the number of bits
572 per word (GMP_NUMB_BITS),
573 - the rounding mode is to nearest (MPFR_RNDN),
574 - internally, the result has to be rounded up to a power of 2.
575 */
576 static void
577 bug20160120 (void)
578 {
579 mpfr_t x, y;
580
581 mpfr_init2 (x, 4 * GMP_NUMB_BITS);
582 mpfr_init2 (y, GMP_NUMB_BITS);
583
584 mpfr_set_ui (x, 1, MPFR_RNDN);
585 mpfr_nextbelow (x);
586 mpfr_sqrt (y, x, MPFR_RNDN);
587 MPFR_ASSERTN(mpfr_check (y));
588 MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
589
590 mpfr_set_prec (y, 2 * GMP_NUMB_BITS);
591 mpfr_sqrt (y, x, MPFR_RNDN);
592 MPFR_ASSERTN(mpfr_check (y));
593 MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
594
595 mpfr_clear(x);
596 mpfr_clear(y);
597 }
598
599 /* Bug in mpfr_sqrt2 when prec(u) = 2*GMP_NUMB_BITS and the exponent of u is
600 odd: the last bit of u is lost. */
601 static void
602 bug20160908 (void)
603 {
604 mpfr_t r, u;
605 int n = GMP_NUMB_BITS, ret;
606
607 mpfr_init2 (r, 2*n - 1);
608 mpfr_init2 (u, 2 * n);
609 mpfr_set_ui_2exp (u, 1, 2*n-2, MPFR_RNDN); /* u=2^(2n-2) with exp(u)=2n-1 */
610 mpfr_nextabove (u);
611 /* now u = 2^(2n-2) + 1/2 */
612 ret = mpfr_sqrt (r, u, MPFR_RNDZ);
613 MPFR_ASSERTN(ret == -1 && mpfr_cmp_ui_2exp (r, 1, n-1) == 0);
614 mpfr_clear (r);
615 mpfr_clear (u);
616 }
617
618 static void
619 testall_rndf (mpfr_prec_t pmax)
620 {
621 mpfr_t a, b, d;
622 mpfr_prec_t pa, pb;
623
624 for (pa = MPFR_PREC_MIN; pa <= pmax; pa++)
625 {
626 mpfr_init2 (a, pa);
627 mpfr_init2 (d, pa);
628 for (pb = MPFR_PREC_MIN; pb <= pmax; pb++)
629 {
630 mpfr_init2 (b, pb);
631 mpfr_set_ui (b, 1, MPFR_RNDN);
632 while (mpfr_cmp_ui (b, 4) < 0)
633 {
634 mpfr_sqrt (a, b, MPFR_RNDF);
635 mpfr_sqrt (d, b, MPFR_RNDD);
636 if (!mpfr_equal_p (a, d))
637 {
638 mpfr_sqrt (d, b, MPFR_RNDU);
639 if (!mpfr_equal_p (a, d))
640 {
641 printf ("Error: mpfr_sqrt(a,b,RNDF) does not "
642 "match RNDD/RNDU\n");
643 printf ("b="); mpfr_dump (b);
644 printf ("a="); mpfr_dump (a);
645 exit (1);
646 }
647 }
648 mpfr_nextabove (b);
649 }
650 mpfr_clear (b);
651 }
652 mpfr_clear (a);
653 mpfr_clear (d);
654 }
655 }
656
657 /* test the case prec = GMP_NUMB_BITS */
658 static void
659 test_sqrt1n (void)
660 {
661 mpfr_t r, u;
662 int inex;
663
664 mpfr_init2 (r, GMP_NUMB_BITS);
665 mpfr_init2 (u, GMP_NUMB_BITS);
666
667 inex = mpfr_set_ui_2exp (u, 17 * 17, 2 * GMP_NUMB_BITS - 10, MPFR_RNDN);
668 MPFR_ASSERTN(inex == 0);
669 inex = mpfr_sqrt (r, u, MPFR_RNDN);
670 MPFR_ASSERTN(inex == 0);
671 MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 17, GMP_NUMB_BITS - 5) == 0);
672
673 inex = mpfr_set_ui_2exp (u, 1, GMP_NUMB_BITS - 2, MPFR_RNDN);
674 MPFR_ASSERTN(inex == 0);
675 inex = mpfr_add_ui (u, u, 1, MPFR_RNDN);
676 MPFR_ASSERTN(inex == 0);
677 inex = mpfr_mul_2exp (u, u, GMP_NUMB_BITS, MPFR_RNDN);
678 MPFR_ASSERTN(inex == 0);
679 /* u = 2^(2*GMP_NUMB_BITS-2) + 2^GMP_NUMB_BITS, thus
680 u = r^2 + 2^GMP_NUMB_BITS with r = 2^(GMP_NUMB_BITS-1).
681 Should round to r+1 to nearest. */
682 inex = mpfr_sqrt (r, u, MPFR_RNDN);
683 MPFR_ASSERTN(inex > 0);
684 inex = mpfr_sub_ui (r, r, 1, MPFR_RNDN);
685 MPFR_ASSERTN(inex == 0);
686 MPFR_ASSERTN(mpfr_cmp_ui_2exp (r, 1, GMP_NUMB_BITS - 1) == 0);
687
688 mpfr_clear (r);
689 mpfr_clear (u);
690 }
691
692 #define TEST_FUNCTION test_sqrt
693 #define TEST_RANDOM_POS 8
694 #include "tgeneric.c"
695
696 int
697 main (void)
698 {
699 mpfr_prec_t p;
700 int k;
701
702 tests_start_mpfr ();
703
704 testall_rndf (16);
705 for (p = MPFR_PREC_MIN; p <= 128; p++)
706 {
707 test_property1 (p, MPFR_RNDN, 0);
708 test_property1 (p, MPFR_RNDU, 0);
709 test_property1 (p, MPFR_RNDA, 0);
710 test_property1 (p, MPFR_RNDN, 1);
711 test_property1 (p, MPFR_RNDU, 1);
712 test_property1 (p, MPFR_RNDA, 1);
713 test_property2 (p, MPFR_RNDN);
714 }
715
716 check_diverse ("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328", 160, "796887792767063979679855997149887366668464780637");
717 special ();
718 check_singular ();
719
720 for (p=2; p<200; p++)
721 for (k=0; k<200; k++)
722 check_inexact (p);
723 check_float();
724
725 check3 ("-0.0", MPFR_RNDN, "0.0");
726 check4 ("6.37983013646045901440e+32", MPFR_RNDN, "5.9bc5036d09e0c@13");
727 check4 ("1.0", MPFR_RNDN, "1");
728 check4 ("1.0", MPFR_RNDZ, "1");
729 check4 ("3.725290298461914062500000e-9", MPFR_RNDN, "4@-4");
730 check4 ("3.725290298461914062500000e-9", MPFR_RNDZ, "4@-4");
731 check4 ("1190456976439861.0", MPFR_RNDZ, "2.0e7957873529a@6");
732 check4 ("1219027943874417664.0", MPFR_RNDZ, "4.1cf2af0e6a534@7");
733 /* the following examples are bugs in Cygnus compiler/system, found by
734 Fabrice Rouillier while porting mpfr to Windows */
735 check4 ("9.89438396044940256501e-134", MPFR_RNDU, "8.7af7bf0ebbee@-56");
736 check4 ("7.86528588050363751914e+31", MPFR_RNDZ, "1.f81fc40f32062@13");
737 check4 ("0.99999999999999988897", MPFR_RNDN, "f.ffffffffffff8@-1");
738 check4 ("1.00000000000000022204", MPFR_RNDN, "1");
739 /* the following examples come from the paper "Number-theoretic Test
740 Generation for Directed Rounding" from Michael Parks, Table 4 */
741
742 check4 ("78652858805036375191418371571712.0", MPFR_RNDN,
743 "1.f81fc40f32063@13");
744 check4 ("38510074998589467860312736661504.0", MPFR_RNDN,
745 "1.60c012a92fc65@13");
746 check4 ("35318779685413012908190921129984.0", MPFR_RNDN,
747 "1.51d17526c7161@13");
748 check4 ("26729022595358440976973142425600.0", MPFR_RNDN,
749 "1.25e19302f7e51@13");
750 check4 ("22696567866564242819241453027328.0", MPFR_RNDN,
751 "1.0ecea7dd2ec3d@13");
752 check4 ("22696888073761729132924856434688.0", MPFR_RNDN,
753 "1.0ecf250e8e921@13");
754 check4 ("36055652513981905145251657416704.0", MPFR_RNDN,
755 "1.5552f3eedcf33@13");
756 check4 ("30189856268896404997497182748672.0", MPFR_RNDN,
757 "1.3853ee10c9c99@13");
758 check4 ("36075288240584711210898775080960.0", MPFR_RNDN,
759 "1.556abe212b56f@13");
760 check4 ("72154663483843080704304789585920.0", MPFR_RNDN,
761 "1.e2d9a51977e6e@13");
762
763 check4 ("78652858805036375191418371571712.0", MPFR_RNDZ,
764 "1.f81fc40f32062@13");
765 check4 ("38510074998589467860312736661504.0", MPFR_RNDZ,
766 "1.60c012a92fc64@13");
767 check4 ("35318779685413012908190921129984.0", MPFR_RNDZ, "1.51d17526c716@13");
768 check4 ("26729022595358440976973142425600.0", MPFR_RNDZ, "1.25e19302f7e5@13");
769 check4 ("22696567866564242819241453027328.0", MPFR_RNDZ,
770 "1.0ecea7dd2ec3c@13");
771 check4 ("22696888073761729132924856434688.0", MPFR_RNDZ, "1.0ecf250e8e92@13");
772 check4 ("36055652513981905145251657416704.0", MPFR_RNDZ,
773 "1.5552f3eedcf32@13");
774 check4 ("30189856268896404997497182748672.0", MPFR_RNDZ,
775 "1.3853ee10c9c98@13");
776 check4 ("36075288240584711210898775080960.0", MPFR_RNDZ,
777 "1.556abe212b56e@13");
778 check4 ("72154663483843080704304789585920.0", MPFR_RNDZ,
779 "1.e2d9a51977e6d@13");
780
781 check4 ("78652858805036375191418371571712.0", MPFR_RNDU,
782 "1.f81fc40f32063@13");
783 check4 ("38510074998589467860312736661504.0", MPFR_RNDU,
784 "1.60c012a92fc65@13");
785 check4 ("35318779685413012908190921129984.0", MPFR_RNDU,
786 "1.51d17526c7161@13");
787 check4 ("26729022595358440976973142425600.0", MPFR_RNDU,
788 "1.25e19302f7e51@13");
789 check4 ("22696567866564242819241453027328.0", MPFR_RNDU,
790 "1.0ecea7dd2ec3d@13");
791 check4 ("22696888073761729132924856434688.0", MPFR_RNDU,
792 "1.0ecf250e8e921@13");
793 check4 ("36055652513981905145251657416704.0", MPFR_RNDU,
794 "1.5552f3eedcf33@13");
795 check4 ("30189856268896404997497182748672.0", MPFR_RNDU,
796 "1.3853ee10c9c99@13");
797 check4 ("36075288240584711210898775080960.0", MPFR_RNDU,
798 "1.556abe212b56f@13");
799 check4 ("72154663483843080704304789585920.0", MPFR_RNDU,
800 "1.e2d9a51977e6e@13");
801
802 check4 ("78652858805036375191418371571712.0", MPFR_RNDD,
803 "1.f81fc40f32062@13");
804 check4 ("38510074998589467860312736661504.0", MPFR_RNDD,
805 "1.60c012a92fc64@13");
806 check4 ("35318779685413012908190921129984.0", MPFR_RNDD, "1.51d17526c716@13");
807 check4 ("26729022595358440976973142425600.0", MPFR_RNDD, "1.25e19302f7e5@13");
808 check4 ("22696567866564242819241453027328.0", MPFR_RNDD,
809 "1.0ecea7dd2ec3c@13");
810 check4 ("22696888073761729132924856434688.0", MPFR_RNDD, "1.0ecf250e8e92@13");
811 check4 ("36055652513981905145251657416704.0", MPFR_RNDD,
812 "1.5552f3eedcf32@13");
813 check4 ("30189856268896404997497182748672.0", MPFR_RNDD,
814 "1.3853ee10c9c98@13");
815 check4 ("36075288240584711210898775080960.0", MPFR_RNDD,
816 "1.556abe212b56e@13");
817 check4 ("72154663483843080704304789585920.0", MPFR_RNDD,
818 "1.e2d9a51977e6d@13");
819
820 /* check that rounding away is just rounding toward plus infinity */
821 check4 ("72154663483843080704304789585920.0", MPFR_RNDA,
822 "1.e2d9a51977e6e@13");
823
824 test_generic (MPFR_PREC_MIN, 300, 15);
825 data_check ("data/sqrt", mpfr_sqrt, "mpfr_sqrt");
826 bad_cases (mpfr_sqrt, mpfr_sqr, "mpfr_sqrt", 8, -256, 255, 4, 128, 800, 50);
827
828 bug20160120 ();
829 bug20160908 ();
830 test_sqrt1n ();
831
832 tests_end_mpfr ();
833 return 0;
834 }
835