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