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