1 /* Test file for mpfr_add and mpfr_sub.
2
3 Copyright 1999-2020 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 https://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 #define N 30000
24
25 #include <float.h>
26
27 #include "mpfr-test.h"
28
29 /* If the precisions are the same, we want to test both mpfr_add1sp
30 and mpfr_add1. */
31
32 /* FIXME: modify check() to test the ternary value and the flags. */
33
34 static int usesp;
35
36 static int
test_add(mpfr_ptr a,mpfr_srcptr b,mpfr_srcptr c,mpfr_rnd_t rnd_mode)37 test_add (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
38 {
39 int res;
40 #ifdef CHECK_EXTERNAL
41 int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
42 if (ok)
43 {
44 mpfr_print_raw (b);
45 printf (" ");
46 mpfr_print_raw (c);
47 }
48 #endif
49 if (usesp || MPFR_ARE_SINGULAR(b,c) || MPFR_SIGN(b) != MPFR_SIGN(c))
50 res = mpfr_add (a, b, c, rnd_mode);
51 else
52 {
53 if (MPFR_GET_EXP(b) < MPFR_GET_EXP(c))
54 res = mpfr_add1(a, c, b, rnd_mode);
55 else
56 res = mpfr_add1(a, b, c, rnd_mode);
57 }
58 #ifdef CHECK_EXTERNAL
59 if (ok)
60 {
61 printf (" ");
62 mpfr_print_raw (a);
63 printf ("\n");
64 }
65 #endif
66 return res;
67 }
68
69 /* checks that xs+ys gives the expected result zs */
70 static void
check(const char * xs,const char * ys,mpfr_rnd_t rnd_mode,unsigned int px,unsigned int py,unsigned int pz,const char * zs)71 check (const char *xs, const char *ys, mpfr_rnd_t rnd_mode,
72 unsigned int px, unsigned int py, unsigned int pz, const char *zs)
73 {
74 mpfr_t xx,yy,zz;
75
76 mpfr_init2 (xx, px);
77 mpfr_init2 (yy, py);
78 mpfr_init2 (zz, pz);
79
80 mpfr_set_str1 (xx, xs);
81 mpfr_set_str1 (yy, ys);
82 test_add (zz, xx, yy, rnd_mode);
83 if (mpfr_cmp_str1 (zz, zs) )
84 {
85 printf ("expected sum is %s, got ", zs);
86 mpfr_out_str (stdout, 10, 0, zz, MPFR_RNDN);
87 printf ("\nmpfr_add failed for x=%s y=%s with rnd_mode=%s\n",
88 xs, ys, mpfr_print_rnd_mode (rnd_mode));
89 exit (1);
90 }
91 mpfr_clears (xx, yy, zz, (mpfr_ptr) 0);
92 }
93
94 static void
check2b(const char * xs,int px,const char * ys,int py,const char * rs,int pz,mpfr_rnd_t rnd_mode)95 check2b (const char *xs, int px,
96 const char *ys, int py,
97 const char *rs, int pz,
98 mpfr_rnd_t rnd_mode)
99 {
100 mpfr_t xx, yy, zz;
101
102 mpfr_init2 (xx,px);
103 mpfr_init2 (yy,py);
104 mpfr_init2 (zz,pz);
105 mpfr_set_str_binary (xx, xs);
106 mpfr_set_str_binary (yy, ys);
107 test_add (zz, xx, yy, rnd_mode);
108 if (mpfr_cmp_str (zz, rs, 2, MPFR_RNDN))
109 {
110 printf ("(2) x=%s,%d y=%s,%d pz=%d,rnd=%s\n",
111 xs, px, ys, py, pz, mpfr_print_rnd_mode (rnd_mode));
112 printf ("got "); mpfr_dump (zz);
113 mpfr_set_str(zz, rs, 2, MPFR_RNDN);
114 printf ("instead of "); mpfr_dump (zz);
115 exit (1);
116 }
117 mpfr_clear(xx); mpfr_clear(yy); mpfr_clear(zz);
118 }
119
120 static void
check64(void)121 check64 (void)
122 {
123 mpfr_t x, t, u;
124
125 mpfr_init (x);
126 mpfr_init (t);
127 mpfr_init (u);
128
129 mpfr_set_prec (x, 29);
130 mpfr_set_str_binary (x, "1.1101001000101111011010010110e-3");
131 mpfr_set_prec (t, 58);
132 mpfr_set_str_binary (t, "0.11100010011111001001100110010111110110011000000100101E-1");
133 mpfr_set_prec (u, 29);
134 test_add (u, x, t, MPFR_RNDD);
135 mpfr_set_str_binary (t, "1.0101011100001000011100111110e-1");
136 if (mpfr_cmp (u, t))
137 {
138 printf ("mpfr_add(u, x, t) failed for prec(x)=29, prec(t)=58\n");
139 printf ("expected "); mpfr_out_str (stdout, 2, 29, t, MPFR_RNDN);
140 puts ("");
141 printf ("got "); mpfr_out_str (stdout, 2, 29, u, MPFR_RNDN);
142 puts ("");
143 exit(1);
144 }
145
146 mpfr_set_prec (x, 4);
147 mpfr_set_str_binary (x, "-1.0E-2");
148 mpfr_set_prec (t, 2);
149 mpfr_set_str_binary (t, "-1.1e-2");
150 mpfr_set_prec (u, 2);
151 test_add (u, x, t, MPFR_RNDN);
152 if ((mp_limb_t) (MPFR_MANT(u)[0] << 2))
153 {
154 printf ("result not normalized for prec=2\n");
155 mpfr_dump (u);
156 exit (1);
157 }
158 mpfr_set_str_binary (t, "-1.0e-1");
159 if (mpfr_cmp (u, t))
160 {
161 printf ("mpfr_add(u, x, t) failed for prec(x)=4, prec(t)=2\n");
162 printf ("expected -1.0e-1\n");
163 printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
164 puts ("");
165 exit (1);
166 }
167
168 mpfr_set_prec (x, 8);
169 mpfr_set_str_binary (x, "-0.10011010"); /* -77/128 */
170 mpfr_set_prec (t, 4);
171 mpfr_set_str_binary (t, "-1.110e-5"); /* -7/128 */
172 mpfr_set_prec (u, 4);
173 test_add (u, x, t, MPFR_RNDN); /* should give -5/8 */
174 mpfr_set_str_binary (t, "-1.010e-1");
175 if (mpfr_cmp (u, t)) {
176 printf ("mpfr_add(u, x, t) failed for prec(x)=8, prec(t)=4\n");
177 printf ("expected -1.010e-1\n");
178 printf ("got "); mpfr_out_str (stdout, 2, 4, u, MPFR_RNDN);
179 puts ("");
180 exit (1);
181 }
182
183 mpfr_set_prec (x, 112); mpfr_set_prec (t, 98); mpfr_set_prec (u, 54);
184 mpfr_set_str_binary (x, "-0.11111100100000000011000011100000101101010001000111E-401");
185 mpfr_set_str_binary (t, "0.10110000100100000101101100011111111011101000111000101E-464");
186 test_add (u, x, t, MPFR_RNDN);
187 if (mpfr_cmp (u, x))
188 {
189 printf ("mpfr_add(u, x, t) failed for prec(x)=112, prec(t)=98\n");
190 exit (1);
191 }
192
193 mpfr_set_prec (x, 92); mpfr_set_prec (t, 86); mpfr_set_prec (u, 53);
194 mpfr_set_str (x, "-5.03525136761487735093e-74", 10, MPFR_RNDN);
195 mpfr_set_str (t, "8.51539046314262304109e-91", 10, MPFR_RNDN);
196 test_add (u, x, t, MPFR_RNDN);
197 if (mpfr_cmp_str1 (u, "-5.0352513676148773509283672e-74") )
198 {
199 printf ("mpfr_add(u, x, t) failed for prec(x)=92, prec(t)=86\n");
200 exit (1);
201 }
202
203 mpfr_set_prec(x, 53); mpfr_set_prec(t, 76); mpfr_set_prec(u, 76);
204 mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
205 mpfr_set_str_binary(t, "-0.1011000101110010000101111111011111010001110011110111100110101011110010011111");
206 mpfr_sub(u, x, t, MPFR_RNDU);
207 mpfr_set_str_binary(t, "0.1011000101110010000101111111011100111111101010011011110110101011101000000100");
208 if (mpfr_cmp(u,t))
209 {
210 printf ("expect "); mpfr_dump (t);
211 printf ("mpfr_add failed for precisions 53-76\n");
212 exit (1);
213 }
214 mpfr_set_prec(x, 53); mpfr_set_prec(t, 108); mpfr_set_prec(u, 108);
215 mpfr_set_str_binary(x, "-0.10010010001001011011110000000000001010011011011110001E-32");
216 mpfr_set_str_binary(t, "-0.101100010111001000010111111101111101000111001111011110011010101111001001111000111011001110011000000000111111");
217 mpfr_sub(u, x, t, MPFR_RNDU);
218 mpfr_set_str_binary(t, "0.101100010111001000010111111101110011111110101001101111011010101110100000001011000010101110011000000000111111");
219 if (mpfr_cmp(u,t))
220 {
221 printf ("expect "); mpfr_dump (t);
222 printf ("mpfr_add failed for precisions 53-108\n");
223 exit (1);
224 }
225 mpfr_set_prec(x, 97); mpfr_set_prec(t, 97); mpfr_set_prec(u, 97);
226 mpfr_set_str_binary(x, "0.1111101100001000000001011000110111101000001011111000100001000101010100011111110010000000000000000E-39");
227 mpfr_set_ui(t, 1, MPFR_RNDN);
228 test_add (u, x, t, MPFR_RNDN);
229 mpfr_set_str_binary(x, "0.1000000000000000000000000000000000000000111110110000100000000101100011011110100000101111100010001E1");
230 if (mpfr_cmp(u,x))
231 {
232 printf ("mpfr_add failed for precision 97\n");
233 exit (1);
234 }
235 mpfr_set_prec(x, 128); mpfr_set_prec(t, 128); mpfr_set_prec(u, 128);
236 mpfr_set_str_binary(x, "0.10101011111001001010111011001000101100111101000000111111111011010100001100011101010001010111111101111010100110111111100101100010E-4");
237 mpfr_set(t, x, MPFR_RNDN);
238 mpfr_sub(u, x, t, MPFR_RNDN);
239 mpfr_set_prec(x, 96); mpfr_set_prec(t, 96); mpfr_set_prec(u, 96);
240 mpfr_set_str_binary(x, "0.111000000001110100111100110101101001001010010011010011100111100011010100011001010011011011000010E-4");
241 mpfr_set(t, x, MPFR_RNDN);
242 mpfr_sub(u, x, t, MPFR_RNDN);
243 mpfr_set_prec(x, 85); mpfr_set_prec(t, 85); mpfr_set_prec(u, 85);
244 mpfr_set_str_binary(x, "0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
245 mpfr_set_str_binary(t, "0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
246 mpfr_sub(u, x, t, MPFR_RNDU);
247 mpfr_sub(x, x, t, MPFR_RNDU);
248 if (mpfr_cmp(x, u) != 0)
249 {
250 printf ("Error in mpfr_sub: u=x-t and x=x-t give different results\n");
251 exit (1);
252 }
253 if (! MPFR_IS_NORMALIZED (u))
254 {
255 printf ("Error in mpfr_sub: result is not msb-normalized (1)\n");
256 exit (1);
257 }
258 mpfr_set_prec(x, 65); mpfr_set_prec(t, 65); mpfr_set_prec(u, 65);
259 mpfr_set_str_binary(x, "0.10011010101000110101010000000011001001001110001011101011111011101E623");
260 mpfr_set_str_binary(t, "0.10011010101000110101010000000011001001001110001011101011111011100E623");
261 mpfr_sub(u, x, t, MPFR_RNDU);
262 if (mpfr_cmp_ui_2exp(u, 1, 558))
263 { /* 2^558 */
264 printf ("Error (1) in mpfr_sub\n");
265 exit (1);
266 }
267
268 mpfr_set_prec(x, 64); mpfr_set_prec(t, 64); mpfr_set_prec(u, 64);
269 mpfr_set_str_binary(x, "0.1000011110101111011110111111000011101011101111101101101100000100E-220");
270 mpfr_set_str_binary(t, "0.1000011110101111011110111111000011101011101111101101010011111101E-220");
271 test_add (u, x, t, MPFR_RNDU);
272 if ((MPFR_MANT(u)[0] & 1) != 1)
273 {
274 printf ("error in mpfr_add with rnd_mode=MPFR_RNDU\n");
275 printf ("b= "); mpfr_dump (x);
276 printf ("c= "); mpfr_dump (t);
277 printf ("b+c="); mpfr_dump (u);
278 exit (1);
279 }
280
281 /* bug found by Norbert Mueller, 14 Sep 2000 */
282 mpfr_set_prec(x, 56); mpfr_set_prec(t, 83); mpfr_set_prec(u, 10);
283 mpfr_set_str_binary(x, "0.10001001011011001111101100110100000101111010010111010111E-7");
284 mpfr_set_str_binary(t, "0.10001001011011001111101100110100000101111010010111010111000000000111110110110000100E-7");
285 mpfr_sub(u, x, t, MPFR_RNDU);
286
287 /* array bound write found by Norbert Mueller, 26 Sep 2000 */
288 mpfr_set_prec(x, 109); mpfr_set_prec(t, 153); mpfr_set_prec(u, 95);
289 mpfr_set_str_binary(x,"0.1001010000101011101100111000110001111111111111111111111111111111111111111111111111111111111111100000000000000E33");
290 mpfr_set_str_binary(t,"-0.100101000010101110110011100011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100101101000000100100001100110111E33");
291 test_add (u, x, t, MPFR_RNDN);
292
293 /* array bound writes found by Norbert Mueller, 27 Sep 2000 */
294 mpfr_set_prec(x, 106); mpfr_set_prec(t, 53); mpfr_set_prec(u, 23);
295 mpfr_set_str_binary(x, "-0.1000011110101111111001010001000100001011000000000000000000000000000000000000000000000000000000000000000000E-59");
296 mpfr_set_str_binary(t, "-0.10000111101011111110010100010001101100011100110100000E-59");
297 mpfr_sub(u, x, t, MPFR_RNDN);
298 mpfr_set_prec(x, 177); mpfr_set_prec(t, 217); mpfr_set_prec(u, 160);
299 mpfr_set_str_binary(x, "-0.111010001011010000111001001010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E35");
300 mpfr_set_str_binary(t, "0.1110100010110100001110010010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111011010011100001111001E35");
301 test_add (u, x, t, MPFR_RNDN);
302 mpfr_set_prec(x, 214); mpfr_set_prec(t, 278); mpfr_set_prec(u, 207);
303 mpfr_set_str_binary(x, "0.1000100110100110101101101101000000010000100111000001001110001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E66");
304 mpfr_set_str_binary(t, "-0.10001001101001101011011011010000000100001001110000010011100010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111011111001001100011E66");
305 test_add (u, x, t, MPFR_RNDN);
306 mpfr_set_prec(x, 32); mpfr_set_prec(t, 247); mpfr_set_prec(u, 223);
307 mpfr_set_str_binary(x, "0.10000000000000000000000000000000E1");
308 mpfr_set_str_binary(t, "0.1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000110001110100000100011110000101110110011101110100110110111111011010111100100000000000000000000000000E0");
309 mpfr_sub(u, x, t, MPFR_RNDN);
310 if (! MPFR_IS_NORMALIZED (u))
311 {
312 printf ("Error in mpfr_sub: result is not msb-normalized (2)\n");
313 exit (1);
314 }
315
316 /* bug found by Nathalie Revol, 21 March 2001 */
317 mpfr_set_prec (x, 65);
318 mpfr_set_prec (t, 65);
319 mpfr_set_prec (u, 65);
320 mpfr_set_str_binary (x, "0.11100100101101001100111011111111110001101001000011101001001010010E-35");
321 mpfr_set_str_binary (t, "0.10000000000000000000000000000000000001110010010110100110011110000E1");
322 mpfr_sub (u, t, x, MPFR_RNDU);
323 if (! MPFR_IS_NORMALIZED (u))
324 {
325 printf ("Error in mpfr_sub: result is not msb-normalized (3)\n");
326 exit (1);
327 }
328
329 /* bug found by Fabrice Rouillier, 27 Mar 2001 */
330 mpfr_set_prec (x, 107);
331 mpfr_set_prec (t, 107);
332 mpfr_set_prec (u, 107);
333 mpfr_set_str_binary (x, "0.10111001001111010010001000000010111111011011011101000001001000101000000000000000000000000000000000000000000E315");
334 mpfr_set_str_binary (t, "0.10000000000000000000000000000000000101110100100101110110000001100101011111001000011101111100100100111011000E350");
335 mpfr_sub (u, x, t, MPFR_RNDU);
336 if (! MPFR_IS_NORMALIZED (u))
337 {
338 printf ("Error in mpfr_sub: result is not msb-normalized (4)\n");
339 exit (1);
340 }
341
342 /* checks that NaN flag is correctly reset */
343 mpfr_set_ui (t, 1, MPFR_RNDN);
344 mpfr_set_ui (u, 1, MPFR_RNDN);
345 mpfr_set_nan (x);
346 test_add (x, t, u, MPFR_RNDN);
347 if (mpfr_cmp_ui (x, 2))
348 {
349 printf ("Error in mpfr_add: 1+1 gives ");
350 mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
351 exit (1);
352 }
353
354 mpfr_clear(x); mpfr_clear(t); mpfr_clear(u);
355 }
356
357 /* check case when c does not overlap with a, but both b and c count
358 for rounding */
359 static void
check_case_1b(void)360 check_case_1b (void)
361 {
362 mpfr_t a, b, c;
363 unsigned int prec_a, prec_b, prec_c, dif;
364
365 mpfr_init (a);
366 mpfr_init (b);
367 mpfr_init (c);
368
369 {
370 prec_a = MPFR_PREC_MIN + (randlimb () % 63);
371 mpfr_set_prec (a, prec_a);
372 for (prec_b = prec_a + 2; prec_b <= 64; prec_b++)
373 {
374 dif = prec_b - prec_a;
375 mpfr_set_prec (b, prec_b);
376 /* b = 1 - 2^(-prec_a) + 2^(-prec_b) */
377 mpfr_set_ui (b, 1, MPFR_RNDN);
378 mpfr_div_2ui (b, b, dif, MPFR_RNDN);
379 mpfr_sub_ui (b, b, 1, MPFR_RNDN);
380 mpfr_div_2ui (b, b, prec_a, MPFR_RNDN);
381 mpfr_add_ui (b, b, 1, MPFR_RNDN);
382 for (prec_c = dif; prec_c <= 64; prec_c++)
383 {
384 /* c = 2^(-prec_a) - 2^(-prec_b) */
385 mpfr_set_prec (c, prec_c);
386 mpfr_set_si (c, -1, MPFR_RNDN);
387 mpfr_div_2ui (c, c, dif, MPFR_RNDN);
388 mpfr_add_ui (c, c, 1, MPFR_RNDN);
389 mpfr_div_2ui (c, c, prec_a, MPFR_RNDN);
390 test_add (a, b, c, MPFR_RNDN);
391 if (mpfr_cmp_ui (a, 1) != 0)
392 {
393 printf ("case (1b) failed for prec_a=%u, prec_b=%u,"
394 " prec_c=%u\n", prec_a, prec_b, prec_c);
395 printf ("b="); mpfr_dump (b);
396 printf ("c="); mpfr_dump (c);
397 printf ("a="); mpfr_dump (a);
398 exit (1);
399 }
400 }
401 }
402 }
403
404 mpfr_clear (a);
405 mpfr_clear (b);
406 mpfr_clear (c);
407 }
408
409 /* check case when c overlaps with a */
410 static void
check_case_2(void)411 check_case_2 (void)
412 {
413 mpfr_t a, b, c, d;
414
415 mpfr_init2 (a, 300);
416 mpfr_init2 (b, 800);
417 mpfr_init2 (c, 500);
418 mpfr_init2 (d, 800);
419
420 mpfr_set_str_binary(a, "1E110"); /* a = 2^110 */
421 mpfr_set_str_binary(b, "1E900"); /* b = 2^900 */
422 mpfr_set_str_binary(c, "1E500"); /* c = 2^500 */
423 test_add (c, c, a, MPFR_RNDZ); /* c = 2^500 + 2^110 */
424 mpfr_sub (d, b, c, MPFR_RNDZ); /* d = 2^900 - 2^500 - 2^110 */
425 test_add (b, b, c, MPFR_RNDZ); /* b = 2^900 + 2^500 + 2^110 */
426 test_add (a, b, d, MPFR_RNDZ); /* a = 2^901 */
427 if (mpfr_cmp_ui_2exp (a, 1, 901))
428 {
429 printf ("b + d fails for b=2^900+2^500+2^110, d=2^900-2^500-2^110\n");
430 printf ("expected 1.0e901, got ");
431 mpfr_out_str (stdout, 2, 0, a, MPFR_RNDN);
432 printf ("\n");
433 exit (1);
434 }
435
436 mpfr_clear (a);
437 mpfr_clear (b);
438 mpfr_clear (c);
439 mpfr_clear (d);
440 }
441
442 /* checks when source and destination are equal */
443 static void
check_same(void)444 check_same (void)
445 {
446 mpfr_t x;
447
448 mpfr_init(x); mpfr_set_ui(x, 1, MPFR_RNDZ);
449 test_add (x, x, x, MPFR_RNDZ);
450 if (mpfr_cmp_ui (x, 2))
451 {
452 printf ("Error when all 3 operands are equal\n");
453 exit (1);
454 }
455 mpfr_clear(x);
456 }
457
458 #define check53(x, y, r, z) check(x, y, r, 53, 53, 53, z)
459
460 #define MAX_PREC 256
461
462 static void
check_inexact(void)463 check_inexact (void)
464 {
465 mpfr_t x, y, z, u;
466 mpfr_prec_t px, py, pu, pz;
467 int inexact, cmp;
468 mpfr_rnd_t rnd;
469
470 mpfr_init (x);
471 mpfr_init (y);
472 mpfr_init (z);
473 mpfr_init (u);
474
475 mpfr_set_prec (x, 2);
476 mpfr_set_str_binary (x, "0.1E-4");
477 mpfr_set_prec (u, 33);
478 mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
479 mpfr_set_prec (y, 31);
480 inexact = test_add (y, x, u, MPFR_RNDN);
481
482 if (inexact != 0)
483 {
484 printf ("Wrong ternary value (2): expected 0, got %d\n", inexact);
485 exit (1);
486 }
487
488 mpfr_set_prec (x, 2);
489 mpfr_set_str_binary (x, "0.1E-4");
490 mpfr_set_prec (u, 33);
491 mpfr_set_str_binary (u, "0.101110100101101100000000111100000E-1");
492 mpfr_set_prec (y, 28);
493 inexact = test_add (y, x, u, MPFR_RNDN);
494
495 if (inexact != 0)
496 {
497 printf ("Wrong ternary value (1): expected 0, got %d\n", inexact);
498 exit (1);
499 }
500
501 for (px = 2; px < MAX_PREC; px++)
502 {
503 mpfr_set_prec (x, px);
504
505 do
506 {
507 mpfr_urandomb (x, RANDS);
508 }
509 while (mpfr_cmp_ui (x, 0) == 0);
510
511 for (pu = 2; pu < MAX_PREC; pu++)
512 {
513 mpfr_set_prec (u, pu);
514
515 do
516 {
517 mpfr_urandomb (u, RANDS);
518 }
519 while (mpfr_cmp_ui (u, 0) == 0);
520
521 py = MPFR_PREC_MIN + (randlimb () % (MAX_PREC - 1));
522 mpfr_set_prec (y, py);
523 pz = mpfr_cmpabs (x, u) >= 0 ?
524 MPFR_EXP(x) - MPFR_EXP(u) :
525 MPFR_EXP(u) - MPFR_EXP(x);
526 /* x + u is exactly representable with precision
527 abs(EXP(x)-EXP(u)) + max(prec(x), prec(u)) + 1 */
528 pz = pz + MAX(MPFR_PREC(x), MPFR_PREC(u)) + 1;
529 mpfr_set_prec (z, pz);
530
531 rnd = RND_RAND_NO_RNDF ();
532 inexact = test_add (z, x, u, rnd);
533 if (inexact != 0)
534 {
535 printf ("z <- x + u should be exact\n");
536 printf ("x="); mpfr_dump (x);
537 printf ("u="); mpfr_dump (u);
538 printf ("z="); mpfr_dump (z);
539 exit (1);
540 }
541
542 rnd = RND_RAND_NO_RNDF ();
543 inexact = test_add (y, x, u, rnd);
544 cmp = mpfr_cmp (y, z);
545 if ((inexact == 0 && cmp != 0) ||
546 (inexact > 0 && cmp <= 0) ||
547 (inexact < 0 && cmp >= 0))
548 {
549 printf ("Wrong ternary value for rnd=%s\n",
550 mpfr_print_rnd_mode (rnd));
551 printf ("expected %d, got %d\n", cmp, inexact);
552 printf ("x="); mpfr_dump (x);
553 printf ("u="); mpfr_dump (u);
554 printf ("y= "); mpfr_dump (y);
555 printf ("x+u="); mpfr_dump (z);
556 exit (1);
557 }
558 }
559 }
560
561 mpfr_clear (x);
562 mpfr_clear (y);
563 mpfr_clear (z);
564 mpfr_clear (u);
565 }
566
567 static void
check_nans(void)568 check_nans (void)
569 {
570 mpfr_t s, x, y;
571
572 mpfr_init2 (x, 8L);
573 mpfr_init2 (y, 8L);
574 mpfr_init2 (s, 8L);
575
576 /* +inf + -inf == nan */
577 mpfr_set_inf (x, 1);
578 mpfr_set_inf (y, -1);
579 test_add (s, x, y, MPFR_RNDN);
580 MPFR_ASSERTN (mpfr_nan_p (s));
581
582 /* +inf + 1 == +inf */
583 mpfr_set_inf (x, 1);
584 mpfr_set_ui (y, 1L, MPFR_RNDN);
585 test_add (s, x, y, MPFR_RNDN);
586 MPFR_ASSERTN (mpfr_inf_p (s));
587 MPFR_ASSERTN (mpfr_sgn (s) > 0);
588
589 /* -inf + 1 == -inf */
590 mpfr_set_inf (x, -1);
591 mpfr_set_ui (y, 1L, MPFR_RNDN);
592 test_add (s, x, y, MPFR_RNDN);
593 MPFR_ASSERTN (mpfr_inf_p (s));
594 MPFR_ASSERTN (mpfr_sgn (s) < 0);
595
596 /* 1 + +inf == +inf */
597 mpfr_set_ui (x, 1L, MPFR_RNDN);
598 mpfr_set_inf (y, 1);
599 test_add (s, x, y, MPFR_RNDN);
600 MPFR_ASSERTN (mpfr_inf_p (s));
601 MPFR_ASSERTN (mpfr_sgn (s) > 0);
602
603 /* 1 + -inf == -inf */
604 mpfr_set_ui (x, 1L, MPFR_RNDN);
605 mpfr_set_inf (y, -1);
606 test_add (s, x, y, MPFR_RNDN);
607 MPFR_ASSERTN (mpfr_inf_p (s));
608 MPFR_ASSERTN (mpfr_sgn (s) < 0);
609
610 mpfr_clear (x);
611 mpfr_clear (y);
612 mpfr_clear (s);
613 }
614
615 static void
check_alloc(void)616 check_alloc (void)
617 {
618 mpfr_t a;
619
620 mpfr_init2 (a, 10000);
621 mpfr_set_prec (a, 53);
622 mpfr_set_ui (a, 15236, MPFR_RNDN);
623 test_add (a, a, a, MPFR_RNDN);
624 mpfr_mul (a, a, a, MPFR_RNDN);
625 mpfr_div (a, a, a, MPFR_RNDN);
626 mpfr_sub (a, a, a, MPFR_RNDN);
627 mpfr_clear (a);
628 }
629
630 static void
check_overflow(void)631 check_overflow (void)
632 {
633 mpfr_t a, b, c;
634 mpfr_prec_t prec_a, prec_b, prec_c;
635 int r, up;
636
637 mpfr_init (a);
638 mpfr_init (b);
639 mpfr_init (c);
640
641 RND_LOOP_NO_RNDF (r)
642 for (prec_a = 2; prec_a <= 128; prec_a += 2)
643 for (prec_b = 2; prec_b <= 128; prec_b += 2)
644 for (prec_c = 2; prec_c <= 128; prec_c += 2)
645 {
646 mpfr_set_prec (a, prec_a);
647 mpfr_set_prec (b, prec_b);
648 mpfr_set_prec (c, prec_c);
649
650 mpfr_setmax (b, mpfr_get_emax ());
651
652 up = r == MPFR_RNDA || r == MPFR_RNDU || r == MPFR_RNDN;
653
654 /* set c with overlap with bits of b: will always overflow */
655 mpfr_set_ui_2exp (c, 1, mpfr_get_emax () - prec_b / 2, MPFR_RNDN);
656 mpfr_nextbelow (c);
657 mpfr_clear_overflow ();
658 test_add (a, b, c, (mpfr_rnd_t) r);
659 if (!mpfr_overflow_p () || (up && !mpfr_inf_p (a)))
660 {
661 printf ("No overflow (1) in check_overflow for rnd=%s\n",
662 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
663 printf ("b="); mpfr_dump (b);
664 printf ("c="); mpfr_dump (c);
665 printf ("a="); mpfr_dump (a);
666 exit (1);
667 }
668
669 if (r == MPFR_RNDZ || r == MPFR_RNDD || prec_a >= prec_b + prec_c)
670 continue;
671
672 /* set c to 111...111 so that ufp(c) = 1/2 ulp(b): will only overflow
673 when prec_a < prec_b + prec_c, and rounding up or to nearest */
674 mpfr_set_ui_2exp (c, 1, mpfr_get_emax () - prec_b, MPFR_RNDN);
675 mpfr_nextbelow (c);
676 mpfr_clear_overflow ();
677 test_add (a, b, c, (mpfr_rnd_t) r);
678 /* b + c is exactly representable iff prec_a >= prec_b + prec_c */
679 if (!mpfr_overflow_p () || !mpfr_inf_p (a))
680 {
681 printf ("No overflow (2) in check_overflow for rnd=%s\n",
682 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
683 printf ("b="); mpfr_dump (b);
684 printf ("c="); mpfr_dump (c);
685 printf ("a="); mpfr_dump (a);
686 exit (1);
687 }
688 }
689
690 mpfr_set_prec (b, 256);
691 mpfr_setmax (b, mpfr_get_emax ());
692 mpfr_set_prec (c, 256);
693 mpfr_set_ui (c, 1, MPFR_RNDN);
694 mpfr_set_exp (c, mpfr_get_emax () - 512);
695 mpfr_set_prec (a, 256);
696 mpfr_clear_overflow ();
697 mpfr_add (a, b, c, MPFR_RNDU);
698 if (!mpfr_overflow_p ())
699 {
700 printf ("No overflow (3) in check_overflow\n");
701 printf ("b="); mpfr_dump (b);
702 printf ("c="); mpfr_dump (c);
703 printf ("a="); mpfr_dump (a);
704 exit (1);
705 }
706
707 mpfr_clear (a);
708 mpfr_clear (b);
709 mpfr_clear (c);
710 }
711
712 static void
check_1111(void)713 check_1111 (void)
714 {
715 mpfr_t one;
716 long n;
717
718 mpfr_init2 (one, MPFR_PREC_MIN);
719 mpfr_set_ui (one, 1, MPFR_RNDN);
720 for (n = 0; n < N; n++)
721 {
722 mpfr_prec_t prec_a, prec_b, prec_c;
723 mpfr_exp_t tb=0, tc, diff;
724 mpfr_t a, b, c, s;
725 int m = 512;
726 int sb, sc;
727 int inex_a, inex_s;
728 mpfr_rnd_t rnd_mode;
729
730 prec_a = MPFR_PREC_MIN + (randlimb () % m);
731 prec_b = MPFR_PREC_MIN + (randlimb () % m);
732 /* we need prec_c > 1 so that % (prec_c - 1) is well defined below */
733 do prec_c = MPFR_PREC_MIN + (randlimb () % m); while (prec_c == 1);
734 mpfr_init2 (a, prec_a);
735 mpfr_init2 (b, prec_b);
736 mpfr_init2 (c, prec_c);
737 /* we need prec_b - (sb != 2) > 0 below */
738 do sb = randlimb () % 3; while (prec_b - (sb != 2) == 0);
739 if (sb != 0)
740 {
741 tb = 1 + (randlimb () % (prec_b - (sb != 2)));
742 mpfr_div_2ui (b, one, tb, MPFR_RNDN);
743 if (sb == 2)
744 mpfr_neg (b, b, MPFR_RNDN);
745 test_add (b, b, one, MPFR_RNDN);
746 }
747 else
748 mpfr_set (b, one, MPFR_RNDN);
749 tc = 1 + (randlimb () % (prec_c - 1));
750 mpfr_div_2ui (c, one, tc, MPFR_RNDN);
751 sc = randlimb () % 2;
752 if (sc)
753 mpfr_neg (c, c, MPFR_RNDN);
754 test_add (c, c, one, MPFR_RNDN);
755 diff = (randlimb () % (2*m)) - m;
756 mpfr_mul_2si (c, c, diff, MPFR_RNDN);
757 rnd_mode = RND_RAND_NO_RNDF ();
758 inex_a = test_add (a, b, c, rnd_mode);
759 mpfr_init2 (s, MPFR_PREC_MIN + 2*m);
760 inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
761 if (inex_s)
762 {
763 printf ("check_1111: result should have been exact.\n");
764 exit (1);
765 }
766 inex_s = mpfr_prec_round (s, prec_a, rnd_mode);
767 if ((inex_a < 0 && inex_s >= 0) ||
768 (inex_a == 0 && inex_s != 0) ||
769 (inex_a > 0 && inex_s <= 0) ||
770 !mpfr_equal_p (a, s))
771 {
772 printf ("check_1111: results are different.\n");
773 printf ("prec_a = %d, prec_b = %d, prec_c = %d\n",
774 (int) prec_a, (int) prec_b, (int) prec_c);
775 printf ("tb = %d, tc = %d, diff = %d, rnd = %s\n",
776 (int) tb, (int) tc, (int) diff,
777 mpfr_print_rnd_mode (rnd_mode));
778 printf ("sb = %d, sc = %d\n", sb, sc);
779 printf ("b = "); mpfr_dump (b);
780 printf ("c = "); mpfr_dump (c);
781 printf ("a = "); mpfr_dump (a);
782 printf ("s = "); mpfr_dump (s);
783 printf ("inex_a = %d, inex_s = %d\n", inex_a, inex_s);
784 exit (1);
785 }
786 mpfr_clear (a);
787 mpfr_clear (b);
788 mpfr_clear (c);
789 mpfr_clear (s);
790 }
791 mpfr_clear (one);
792 }
793
794 static void
check_1minuseps(void)795 check_1minuseps (void)
796 {
797 static mpfr_prec_t prec_a[] = {
798 MPFR_PREC_MIN, 30, 31, 32, 33, 62, 63, 64, 65, 126, 127, 128, 129
799 };
800 static int supp_b[] = {
801 0, 1, 2, 3, 4, 29, 30, 31, 32, 33, 34, 35, 61, 62, 63, 64, 65, 66, 67
802 };
803 mpfr_t a, b, c;
804 unsigned int ia, ib, ic;
805
806 mpfr_init2 (c, MPFR_PREC_MIN);
807
808 for (ia = 0; ia < numberof (prec_a); ia++)
809 for (ib = 0; ib < numberof (supp_b); ib++)
810 {
811 mpfr_prec_t prec_b;
812 int rnd_mode;
813
814 prec_b = prec_a[ia] + supp_b[ib];
815
816 mpfr_init2 (a, prec_a[ia]);
817 mpfr_init2 (b, prec_b);
818
819 mpfr_set_ui (c, 1, MPFR_RNDN);
820 mpfr_div_ui (b, c, prec_a[ia], MPFR_RNDN);
821 mpfr_sub (b, c, b, MPFR_RNDN); /* b = 1 - 2^(-prec_a) */
822
823 for (ic = 0; ic < numberof (supp_b); ic++)
824 for (rnd_mode = 0; rnd_mode < MPFR_RND_MAX; rnd_mode++)
825 {
826 mpfr_t s;
827 int inex_a, inex_s;
828
829 if (rnd_mode == MPFR_RNDF)
830 continue; /* inex_a, inex_s make no sense */
831
832 mpfr_set_ui (c, 1, MPFR_RNDN);
833 mpfr_div_ui (c, c, prec_a[ia] + supp_b[ic], MPFR_RNDN);
834 inex_a = test_add (a, b, c, (mpfr_rnd_t) rnd_mode);
835 mpfr_init2 (s, 256);
836 inex_s = test_add (s, b, c, MPFR_RNDN); /* exact */
837 if (inex_s)
838 {
839 printf ("check_1minuseps: result should have been exact "
840 "(ia = %u, ib = %u, ic = %u)\n", ia, ib, ic);
841 exit (1);
842 }
843 inex_s = mpfr_prec_round (s, prec_a[ia], (mpfr_rnd_t) rnd_mode);
844 if ((inex_a < 0 && inex_s >= 0) ||
845 (inex_a == 0 && inex_s != 0) ||
846 (inex_a > 0 && inex_s <= 0) ||
847 !mpfr_equal_p (a, s))
848 {
849 printf ("check_1minuseps: results are different.\n");
850 printf ("ia = %u, ib = %u, ic = %u\n", ia, ib, ic);
851 exit (1);
852 }
853 mpfr_clear (s);
854 }
855
856 mpfr_clear (a);
857 mpfr_clear (b);
858 }
859
860 mpfr_clear (c);
861 }
862
863 /* Test case bk == 0 in add1.c (b has entirely been read and
864 c hasn't been taken into account). */
865 static void
coverage_bk_eq_0(void)866 coverage_bk_eq_0 (void)
867 {
868 mpfr_t a, b, c;
869 int inex;
870
871 mpfr_init2 (a, GMP_NUMB_BITS);
872 mpfr_init2 (b, 2 * GMP_NUMB_BITS);
873 mpfr_init2 (c, GMP_NUMB_BITS);
874
875 mpfr_set_ui_2exp (b, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
876 mpfr_sub_ui (b, b, 1, MPFR_RNDN);
877 /* b = 111...111 (in base 2) where the 1's fit 2 whole limbs */
878
879 mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN); /* c = 1/2 */
880
881 inex = mpfr_add (a, b, c, MPFR_RNDU);
882 mpfr_set_ui_2exp (c, 1, 2 * GMP_NUMB_BITS, MPFR_RNDN);
883 if (! mpfr_equal_p (a, c))
884 {
885 printf ("Error in coverage_bk_eq_0\n");
886 printf ("Expected ");
887 mpfr_dump (c);
888 printf ("Got ");
889 mpfr_dump (a);
890 exit (1);
891 }
892 MPFR_ASSERTN (inex > 0);
893
894 mpfr_clear (a);
895 mpfr_clear (b);
896 mpfr_clear (c);
897 }
898
899 static void
tests(void)900 tests (void)
901 {
902 check_alloc ();
903 check_nans ();
904 check_inexact ();
905 check_case_1b ();
906 check_case_2 ();
907 check64();
908 coverage_bk_eq_0 ();
909
910 check("293607738.0", "1.9967571564050541e-5", MPFR_RNDU, 64, 53, 53,
911 "2.9360773800002003e8");
912 check("880524.0", "-2.0769715792901673e-5", MPFR_RNDN, 64, 53, 53,
913 "8.8052399997923023e5");
914 check("1196426492.0", "-1.4218093058435347e-3", MPFR_RNDN, 64, 53, 53,
915 "1.1964264919985781e9");
916 check("982013018.0", "-8.941829477291838e-7", MPFR_RNDN, 64, 53, 53,
917 "9.8201301799999905e8");
918 check("1092583421.0", "1.0880649218158844e9", MPFR_RNDN, 64, 53, 53,
919 "2.1806483428158846e9");
920 check("1.8476886419022969e-6", "961494401.0", MPFR_RNDN, 53, 64, 53,
921 "9.6149440100000179e8");
922 check("-2.3222118418069868e5", "1229318102.0", MPFR_RNDN, 53, 64, 53,
923 "1.2290858808158193e9");
924 check("-3.0399171300395734e-6", "874924868.0", MPFR_RNDN, 53, 64, 53,
925 "8.749248679999969e8");
926 check("9.064246624706179e1", "663787413.0", MPFR_RNDN, 53, 64, 53,
927 "6.6378750364246619e8");
928 check("-1.0954322421551264e2", "281806592.0", MPFR_RNDD, 53, 64, 53,
929 "2.8180648245677572e8");
930 check("5.9836930386056659e-8", "1016217213.0", MPFR_RNDN, 53, 64, 53,
931 "1.0162172130000001e9");
932 check("-1.2772161928500301e-7", "1237734238.0", MPFR_RNDN, 53, 64, 53,
933 "1.2377342379999998e9");
934 check("-4.567291988483277e8", "1262857194.0", MPFR_RNDN, 53, 64, 53,
935 "8.0612799515167236e8");
936 check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 53, 53,
937 "2.4380935175292528e8");
938 check("4.7719471752925262e7", "196089880.0", MPFR_RNDN, 53, 64, 53,
939 "2.4380935175292528e8");
940 check("-1.716113812768534e-140", "1271212614.0", MPFR_RNDZ, 53, 64, 53,
941 "1.2712126139999998e9");
942 check("-1.2927455200185474e-50", "1675676122.0", MPFR_RNDD, 53, 64, 53,
943 "1.6756761219999998e9");
944
945 check53("1.22191250737771397120e+20", "948002822.0", MPFR_RNDN,
946 "122191250738719408128.0");
947 check53("9966027674114492.0", "1780341389094537.0", MPFR_RNDN,
948 "11746369063209028.0");
949 check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
950 MPFR_RNDN, "3.5274425367757071711e272");
951 check_same();
952 check53("6.14384195492641560499e-02", "-6.14384195401037683237e-02",
953 MPFR_RNDU, "9.1603877261370314499e-12");
954 check53("1.16809465359248765399e+196", "7.92883212101990665259e+196",
955 MPFR_RNDU, "9.0969267746123943065e196");
956 check53("3.14553393112021279444e-67", "3.14553401015952024126e-67", MPFR_RNDU,
957 "6.2910679412797336946e-67");
958
959 check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDN,
960 "5.4388530464436950905e185");
961 check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDZ,
962 "5.4388530464436944867e185");
963 check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDU,
964 "5.4388530464436950905e185");
965 check53("5.43885304644369509058e+185","-1.87427265794105342763e-57",MPFR_RNDD,
966 "5.4388530464436944867e185");
967
968 check2b("1.001010101110011000000010100101110010111001010000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e358",187,
969 "-1.11100111001101100010001111111110101101110001000000000000000000000000000000000000000000e160",87,
970 "1.001010101110011000000010100101110010111001010000000111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e358",178,
971 MPFR_RNDD);
972 check2b("-1.111100100011100111010101010101001010100100000111001000000000000000000e481",70,
973 "1.1111000110100011110101111110110010010000000110101000000000000000e481",65,
974 "-1.001010111111101011010000001100011101100101000000000000000000e472",61,
975 MPFR_RNDD);
976 check2b("1.0100010111010000100101000000111110011100011001011010000000000000000000000000000000e516",83,
977 "-1.1001111000100001011100000001001100110011110010111111000000e541",59,
978 "-1.1001111000100001011011110111000001001011100000011110100000110001110011010011000000000000000000000000000000000000000000000000e541",125,
979 MPFR_RNDZ);
980 check2b("-1.0010111100000100110001011011010000000011000111101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",155,
981 "-1.00111110100011e239",15,
982 "-1.00101111000001001100101010101110001100110001111010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e261",159,
983 MPFR_RNDD);
984 check2b("-1.110111000011111011000000001001111101101001010100111000000000000000000000000e880",76,
985 "-1.1010010e-634",8,
986 "-1.11011100001111101100000000100111110110100101010011100000000000000000000000e880",75,
987 MPFR_RNDZ);
988 check2b("1.00100100110110101001010010101111000001011100100101010000000000000000000000000000e-530",81,
989 "-1.101101111100000111000011001010110011001011101001110100000e-908",58,
990 "1.00100100110110101001010010101111000001011100100101010e-530",54,
991 MPFR_RNDN);
992 check2b("1.0101100010010111101000000001000010010010011000111011000000000000000000000000000000000000000000000000000000000000000000e374",119,
993 "1.11100101100101e358",15,
994 "1.01011000100110011000010110100100100100100110001110110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e374",150,
995 MPFR_RNDZ);
996 check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
997 "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
998 "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
999 MPFR_RNDZ);
1000 check2b("-1.011110000111101011100001100110100011100101000011011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-189",175,
1001 "1.1e631",2,
1002 "1.011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111e631",115,
1003 MPFR_RNDZ);
1004 check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
1005 "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
1006 "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
1007 MPFR_RNDU);
1008 check2b("-1.101011101001011101100011001000001100010100001101011000000000000000000000000000000000000000000e-449",94,
1009 "-1.01111101010111000011000110011101000111001100110111100000000000000e-429",66,
1010 "-1.01111101010111000100110010000110100100101111111111101100010100001101011000000000000000000000000000000000000000e-429",111,
1011 MPFR_RNDD);
1012 check2b("-1.1001000011101000110000111110010100100101110101111100000000000000000000000000000000000000000000000000000000e-72",107,
1013 "-1.001100011101100100010101101010101011010010111111010000000000000000000000000000e521",79,
1014 "-1.00110001110110010001010110101010101101001011111101000000000000000000000000000000000000000000000001e521",99,
1015 MPFR_RNDD);
1016 check2b("-1.01010001111000000101010100100100110101011011100001110000000000e498",63,
1017 "1.010000011010101111000100111100011100010101011110010100000000000e243",64,
1018 "-1.010100011110000001010101001001001101010110111000011100000000000e498",64,
1019 MPFR_RNDN);
1020 check2b("1.00101100010101000011010000011000111111011110010111000000000000000000000000000000000000000000000000000000000e178",108,
1021 "-1.10101101010101000110011011111001001101111111110000100000000e160",60,
1022 "1.00101100010100111100100011000011111001000010011101110010000000001111100000000000000000000000000000000000e178",105,
1023 MPFR_RNDN);
1024 check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
1025 "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
1026 "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
1027 MPFR_RNDU);
1028 check2b("-1.100000111100101001100111011100011011000001101001111100000000000000000000000000e843",79,
1029 "-1.1101101010110000001001000100001100110011000110110111000000000000000000000000000000000000000000e414",95,
1030 "-1.1000001111001010011001110111000110110000011010100000e843",53,
1031 MPFR_RNDD);
1032 check2b("-1.110110010110100010100011000110111001010000010111110000000000e-415",61,
1033 "-1.0000100101100001111100110011111111110100011101101011000000000000000000e751",71,
1034 "-1.00001001011000011111001100111111111101000111011010110e751",54,
1035 MPFR_RNDN);
1036 check2b("-1.1011011011110001001101010101001000010100010110111101000000000000000000000e258",74,
1037 "-1.00011100010110110101001011000100100000100010101000010000000000000000000000000000000000000000000000e268",99,
1038 "-1.0001110011001001000011110001000111010110101011110010011011110100000000000000000000000000000000000000e268",101,
1039 MPFR_RNDD);
1040 check2b("-1.1011101010011101011000000100100110101101101110000001000000000e629",62,
1041 "1.111111100000011100100011100000011101100110111110111000000000000000000000000000000000000000000e525",94,
1042 "-1.101110101001110101100000010010011010110110111000000011111111111111111111111111111111111111111111111111101e629",106,
1043 MPFR_RNDD);
1044 check2b("1.111001000010001100010000001100000110001011110111011000000000000000000000000000000000000e152",88,
1045 "1.111110111001100100000100111111010111000100111111001000000000000000e152",67,
1046 "1.1110111111011110000010101001011011101010000110110100e153",53,
1047 MPFR_RNDN);
1048 check2b("1.000001100011110010110000110100001010101101111011110100e696",55,
1049 "-1.1011001111011100100001011110100101010101110111010101000000000000000000000000000000000000000000000000000000000000e730",113,
1050 "-1.1011001111011100100001011110100100010100010011100010e730",53,
1051 MPFR_RNDN);
1052 check2b("-1.11010111100001001111000001110101010010001111111001100000000000000000000000000000000000000000000000000000000000e530",111,
1053 "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000e530",99,
1054 "-1.1000110011110011101010101101111101010011011111000000000000000e528",62,
1055 MPFR_RNDD);
1056 check2b("-1.0001100010010100111101101011101000100100010011100011000000000000000000000000000000000000000000000000000000000e733",110,
1057 "-1.001000000111110010100101010100110111001111011011001000000000000000000000000000000000000000000000000000000000e710",109,
1058 "-1.000110001001010011111000111110110001110110011000110110e733",55,
1059 MPFR_RNDN);
1060 check2b("-1.1101011110000100111100000111010101001000111111100110000000000000000000000e530",74,
1061 "1.01110100010010000000010110111101011101000001111101100000000000000000000000000000000000000000000000000000000000e530",111,
1062 "-1.10001100111100111010101011011111010100110111110000000000000000000000000000e528",75,
1063 MPFR_RNDU);
1064 check2b("1.00110011010100111110011010110100111101110101100100110000000000000000000000000000000000000000000000e559",99,
1065 "-1.011010110100111011100110100110011100000000111010011000000000000000e559",67,
1066 "-1.101111111101011111111111001001100100011100001001100000000000000000000000000000000000000000000e556",94,
1067 MPFR_RNDU);
1068 check2b("-1.100101111110110000000110111111011010011101101111100100000000000000e-624",67,
1069 "1.10111010101110100000010110101000000000010011100000100000000e-587",60,
1070 "1.1011101010111010000001011010011111110100011110001011111111001000000100101100010010000011100000000000000000000e-587",110,
1071 MPFR_RNDU);
1072 check2b("-1.10011001000010100000010100100110110010011111101111000000000000000000000000000000000000000000000000000000000000000000e-172",117,
1073 "1.111011100000101010110000100100110100100001001000011100000000e-173",61,
1074 "-1.0100010000001001010110011011101001001011101011110001000000000000000e-173",68,
1075 MPFR_RNDZ);
1076 check2b("1.1000111000110010101001010011010011101100010110001001000000000000000000000000000000000000000000000000e167",101,
1077 "1.0011110010000110000000101100100111000001110110110000000000000000000000000e167",74,
1078 "1.01100101010111000101001111111111010101110001100111001000000000000000000000000000000000000000000000000000e168",105,
1079 MPFR_RNDZ);
1080 check2b("1.100101111111110010100101110111100001110000100001010000000000000000000000000000000000000000000000e808",97,
1081 "-1.1110011001100000100000111111110000110010100111001011000000000000000000000000000000e807",83,
1082 "1.01001001100110001100011111000000000001011010010111010000000000000000000000000000000000000000000e807",96,
1083 MPFR_RNDN);
1084 check2b("1e128",128,
1085 "1e0",128,
1086 "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e0",256,
1087 MPFR_RNDN);
1088 check2b("0.10000000000000000011101111111110110110001100010110100011010000110101101101010010000110110011100110001101110010111011011110010101e1",128,
1089 "0.11110011001100100001111011100010010100011011011111111110101001101001101011100101011110101111111100010010100010100111110110011001e-63",128,
1090 "0.10000000000000000011101111111110110110001100010110100011010001000100111010000100001110100001101111011111100000111011011000111100e1",128,
1091 MPFR_RNDN);
1092 check2b("0.101000111001110100111100000010110010011101001011101001001101101000010100010000011100110110110011011000001110110101100111010110011101000111010011110001010001110110110011111011011100101011111100e-2",192,
1093 "0.101101100000111110011110000110001000110110010010110000111101110010111010100110000000000110010100010001000001011011101010111010101011010110011011011110110111001000111001101000010101111010010010e-130",192,
1094 "0.101000111001110100111100000010110010011101001011101001001101101000010100010000011100110110110011011000001110110101100111010110101000011111100011011000110011011001000001100000001000111011011001e-2",192,
1095 MPFR_RNDN);
1096
1097 /* Checking double precision (53 bits) */
1098 check53("-8.22183238641455905806e-19", "7.42227178769761587878e-19",MPFR_RNDD,
1099 "-7.9956059871694317927e-20");
1100 check53("5.82106394662028628236e+234","-5.21514064202368477230e+89",MPFR_RNDD,
1101 "5.8210639466202855763e234");
1102 check53("5.72931679569871602371e+122","-5.72886070363264321230e+122",
1103 MPFR_RNDN, "4.5609206607281141508e118");
1104 check53("-5.09937369394650450820e+238", "2.70203299854862982387e+250",
1105 MPFR_RNDD, "2.7020329985435301323e250");
1106 check53("-2.96695924472363684394e+27", "1.22842938251111500000e+16",MPFR_RNDD,
1107 "-2.96695924471135255027e27");
1108 check53("1.74693641655743793422e-227", "-7.71776956366861843469e-229",
1109 MPFR_RNDN, "1.669758720920751867e-227");
1110 /* x = -7883040437021647.0; for (i=0; i<468; i++) x = x / 2.0;*/
1111 check53("-1.03432206392780011159e-125", "1.30127034799251347548e-133",
1112 MPFR_RNDN,
1113 "-1.0343220509150965661100887242027378881805094180354e-125");
1114 check53("1.05824655795525779205e+71", "-1.06022698059744327881e+71",MPFR_RNDZ,
1115 "-1.9804226421854867632e68");
1116 check53("-5.84204911040921732219e+240", "7.26658169050749590763e+240",
1117 MPFR_RNDD, "1.4245325800982785854e240");
1118 check53("1.00944884131046636376e+221","2.33809162651471520268e+215",MPFR_RNDN,
1119 "1.0094511794020929787e221");
1120 /*x = 7045852550057985.0; for (i=0; i<986; i++) x = x / 2.0;*/
1121 check53("4.29232078932667367325e-278",
1122 "1.0773525047389793833221116707010783793203080117586e-281"
1123 , MPFR_RNDU, "4.2933981418314132787e-278");
1124 check53("5.27584773801377058681e-80", "8.91207657803547196421e-91", MPFR_RNDN,
1125 "5.2758477381028917269e-80");
1126 check53("2.99280481918991653800e+272", "5.34637717585790933424e+271",
1127 MPFR_RNDN, "3.5274425367757071711e272");
1128 check53("4.67302514390488041733e-184", "2.18321376145645689945e-190",
1129 MPFR_RNDN, "4.6730273271186420541e-184");
1130 check53("5.57294120336300389254e+71", "2.60596167942024924040e+65", MPFR_RNDZ,
1131 "5.5729438093246831053e71");
1132 check53("6.6052588496951015469e24", "4938448004894539.0", MPFR_RNDU,
1133 "6.6052588546335505068e24");
1134 check53("1.23056185051606761523e-190", "1.64589756643433857138e-181",
1135 MPFR_RNDU, "1.6458975676649006598e-181");
1136 check53("2.93231171510175981584e-280", "3.26266919161341483877e-273",
1137 MPFR_RNDU, "3.2626694848445867288e-273");
1138 check53("5.76707395945001907217e-58", "4.74752971449827687074e-51", MPFR_RNDD,
1139 "4.747530291205672325e-51");
1140 check53("277363943109.0", "11.0", MPFR_RNDN, "277363943120.0");
1141 check53("1.44791789689198883921e-140", "-1.90982880222349071284e-121",
1142 MPFR_RNDN, "-1.90982880222349071e-121");
1143
1144
1145 /* tests for particular cases (Vincent Lefevre, 22 Aug 2001) */
1146 check53("9007199254740992.0", "1.0", MPFR_RNDN, "9007199254740992.0");
1147 check53("9007199254740994.0", "1.0", MPFR_RNDN, "9007199254740996.0");
1148 check53("9007199254740992.0", "-1.0", MPFR_RNDN, "9007199254740991.0");
1149 check53("9007199254740994.0", "-1.0", MPFR_RNDN, "9007199254740992.0");
1150 check53("9007199254740996.0", "-1.0", MPFR_RNDN, "9007199254740996.0");
1151
1152 check_overflow ();
1153 check_1111 ();
1154 check_1minuseps ();
1155 }
1156
1157 static void
check_extreme(void)1158 check_extreme (void)
1159 {
1160 mpfr_t u, v, w, x, y;
1161 int i, inex, r;
1162
1163 mpfr_inits2 (32, u, v, w, x, y, (mpfr_ptr) 0);
1164 mpfr_setmin (u, mpfr_get_emax ());
1165 mpfr_setmax (v, mpfr_get_emin ());
1166 mpfr_setmin (w, mpfr_get_emax () - 40);
1167 RND_LOOP (r)
1168 for (i = 0; i < 2; i++)
1169 {
1170 mpfr_add (x, u, v, (mpfr_rnd_t) r);
1171 mpfr_set_prec (y, 64);
1172 inex = mpfr_add (y, u, w, MPFR_RNDN);
1173 MPFR_ASSERTN (inex == 0);
1174 mpfr_prec_round (y, 32, (mpfr_rnd_t) r);
1175 /* for RNDF, the rounding directions are not necessarily consistent */
1176 if (! mpfr_equal_p (x, y) && r != MPFR_RNDF)
1177 {
1178 printf ("Error in u + v (%s)\n",
1179 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
1180 printf ("u = ");
1181 mpfr_dump (u);
1182 printf ("v = ");
1183 mpfr_dump (v);
1184 printf ("Expected ");
1185 mpfr_dump (y);
1186 printf ("Got ");
1187 mpfr_dump (x);
1188 exit (1);
1189 }
1190 mpfr_neg (v, v, MPFR_RNDN);
1191 mpfr_neg (w, w, MPFR_RNDN);
1192 }
1193 mpfr_clears (u, v, w, x, y, (mpfr_ptr) 0);
1194 }
1195
1196 static void
testall_rndf(mpfr_prec_t pmax)1197 testall_rndf (mpfr_prec_t pmax)
1198 {
1199 mpfr_t a, b, c, d;
1200 mpfr_prec_t pa, pb, pc;
1201 mpfr_exp_t eb;
1202
1203 for (pa = MPFR_PREC_MIN; pa <= pmax; pa++)
1204 {
1205 mpfr_init2 (a, pa);
1206 mpfr_init2 (d, pa);
1207 for (pb = MPFR_PREC_MIN; pb <= pmax; pb++)
1208 {
1209 mpfr_init2 (b, pb);
1210 for (eb = 0; eb <= pmax + 3; eb ++)
1211 {
1212 mpfr_set_ui_2exp (b, 1, eb, MPFR_RNDN);
1213 while (mpfr_cmp_ui_2exp (b, 1, eb + 1) < 0)
1214 {
1215 for (pc = MPFR_PREC_MIN; pc <= pmax; pc++)
1216 {
1217 mpfr_init2 (c, pc);
1218 mpfr_set_ui (c, 1, MPFR_RNDN);
1219 while (mpfr_cmp_ui (c, 2) < 0)
1220 {
1221 mpfr_add (a, b, c, MPFR_RNDF);
1222 mpfr_add (d, b, c, MPFR_RNDD);
1223 if (!mpfr_equal_p (a, d))
1224 {
1225 mpfr_add (d, b, c, MPFR_RNDU);
1226 if (!mpfr_equal_p (a, d))
1227 {
1228 printf ("Error: mpfr_add(a,b,c,RNDF) does not "
1229 "match RNDD/RNDU\n");
1230 printf ("b="); mpfr_dump (b);
1231 printf ("c="); mpfr_dump (c);
1232 printf ("a="); mpfr_dump (a);
1233 exit (1);
1234 }
1235 }
1236 mpfr_nextabove (c);
1237 }
1238 mpfr_clear (c);
1239 }
1240 mpfr_nextabove (b);
1241 }
1242 }
1243 mpfr_clear (b);
1244 }
1245 mpfr_clear (a);
1246 mpfr_clear (d);
1247 }
1248 }
1249
1250 static void
test_rndf_exact(mp_size_t pmax)1251 test_rndf_exact (mp_size_t pmax)
1252 {
1253 mpfr_t a, b, c, d;
1254 mpfr_prec_t pa, pb, pc;
1255 mpfr_exp_t eb;
1256
1257 for (pa = MPFR_PREC_MIN; pa <= pmax; pa++)
1258 {
1259 /* only check pa mod GMP_NUMB_BITS = -2, -1, 0, 1, 2 */
1260 if ((pa + 2) % GMP_NUMB_BITS > 4)
1261 continue;
1262 mpfr_init2 (a, pa);
1263 mpfr_init2 (d, pa);
1264 for (pb = MPFR_PREC_MIN; pb <= pmax; pb++)
1265 {
1266 if ((pb + 2) % GMP_NUMB_BITS > 4)
1267 continue;
1268 mpfr_init2 (b, pb);
1269 for (eb = 0; eb <= pmax + 3; eb ++)
1270 {
1271 mpfr_urandomb (b, RANDS);
1272 mpfr_mul_2ui (b, b, eb, MPFR_RNDN);
1273 for (pc = MPFR_PREC_MIN; pc <= pmax; pc++)
1274 {
1275 if ((pc + 2) % GMP_NUMB_BITS > 4)
1276 continue;
1277 mpfr_init2 (c, pc);
1278 mpfr_urandomb (c, RANDS);
1279 mpfr_add (a, b, c, MPFR_RNDF);
1280 mpfr_add (d, b, c, MPFR_RNDD);
1281 if (!mpfr_equal_p (a, d))
1282 {
1283 mpfr_add (d, b, c, MPFR_RNDU);
1284 if (!mpfr_equal_p (a, d))
1285 {
1286 printf ("Error: mpfr_add(a,b,c,RNDF) does not "
1287 "match RNDD/RNDU\n");
1288 printf ("b="); mpfr_dump (b);
1289 printf ("c="); mpfr_dump (c);
1290 printf ("a="); mpfr_dump (a);
1291 exit (1);
1292 }
1293 }
1294
1295 /* now make the low bits from c match those from b */
1296 mpfr_sub (c, b, d, MPFR_RNDN);
1297 mpfr_add (a, b, c, MPFR_RNDF);
1298 mpfr_add (d, b, c, MPFR_RNDD);
1299 if (!mpfr_equal_p (a, d))
1300 {
1301 mpfr_add (d, b, c, MPFR_RNDU);
1302 if (!mpfr_equal_p (a, d))
1303 {
1304 printf ("Error: mpfr_add(a,b,c,RNDF) does not "
1305 "match RNDD/RNDU\n");
1306 printf ("b="); mpfr_dump (b);
1307 printf ("c="); mpfr_dump (c);
1308 printf ("a="); mpfr_dump (a);
1309 exit (1);
1310 }
1311 }
1312
1313 mpfr_clear (c);
1314 }
1315 }
1316 mpfr_clear (b);
1317 }
1318 mpfr_clear (a);
1319 mpfr_clear (d);
1320 }
1321 }
1322
1323 #define TEST_FUNCTION test_add
1324 #define TWO_ARGS
1325 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
1326 #include "tgeneric.c"
1327
1328 int
main(int argc,char * argv[])1329 main (int argc, char *argv[])
1330 {
1331 tests_start_mpfr ();
1332
1333 usesp = 0;
1334 tests ();
1335
1336 #ifndef CHECK_EXTERNAL /* no need to check twice */
1337 usesp = 1;
1338 tests ();
1339 #endif
1340
1341 test_rndf_exact (200);
1342 testall_rndf (7);
1343 check_extreme ();
1344
1345 test_generic (MPFR_PREC_MIN, 1000, 100);
1346
1347 tests_end_mpfr ();
1348 return 0;
1349 }
1350