xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tstrtofr.c (revision a45db23f655e22f0c2354600d3b3c2cb98abf2dc)
1 /* Test file for mpfr_set_str.
2 
3 Copyright 2004-2023 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 #include "mpfr-test.h"
24 
25 /* The implicit \0 is useless, but we do not write num_to_text[62] otherwise
26    g++ complains. */
27 static const char num_to_text36[] = "0123456789abcdefghijklmnopqrstuvwxyz";
28 static const char num_to_text62[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
29   "abcdefghijklmnopqrstuvwxyz";
30 
31 static void
32 check_special (void)
33 {
34   mpfr_t x, y;
35   int i, res;
36   char *s;
37 
38   mpfr_init (x);
39   mpfr_init (y);
40 
41   /* Check dummy case */
42   res = mpfr_strtofr (x, "1234567.89E1", NULL, 10, MPFR_RNDN);
43   mpfr_set_str (y, "1234567.89E1", 10, MPFR_RNDN);
44   if (mpfr_cmp (x, y))
45     {
46       printf ("Results differ between strtofr and set_str.\n"
47               " set_str gives: ");
48       mpfr_dump (y);
49       printf (" strtofr gives: ");
50       mpfr_dump (x);
51       exit (1);
52     }
53 
54   /* Check NAN  */
55   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
56   res = mpfr_strtofr (x, "NaN", &s, 10, MPFR_RNDN);
57   if (res != 0 || !mpfr_nan_p (x) || *s != 0)
58     {
59       printf ("Error for setting NAN (1)\n");
60       exit (1);
61     }
62   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
63   res = mpfr_strtofr (x, "+NaN", &s, 10, MPFR_RNDN);
64   if (res != 0 || !mpfr_nan_p (x) || *s != 0)
65     {
66       printf ("Error for setting +NAN (1)\n");
67       exit (1);
68     }
69   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
70   res = mpfr_strtofr (x, " -NaN", &s, 10, MPFR_RNDN);
71   if (res != 0 || !mpfr_nan_p (x) || *s != 0)
72     {
73       printf ("Error for setting -NAN (1)\n");
74       exit (1);
75     }
76   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
77   res = mpfr_strtofr (x, "@nAn@xx", &s, 16, MPFR_RNDN);
78   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "xx") )
79     {
80       printf ("Error for setting NAN (2)\n");
81       exit (1);
82     }
83   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
84   res = mpfr_strtofr (x, "NAN(abcdEDF__1256)Hello", &s, 10, MPFR_RNDN);
85   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "Hello") )
86     {
87       printf ("Error for setting NAN (3)\n");
88       exit (1);
89     }
90   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
91   res = mpfr_strtofr (x, "NAN(abcdEDF)__1256)Hello", &s, 10, MPFR_RNDN);
92   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "__1256)Hello") )
93     {
94       printf ("Error for setting NAN (4)\n");
95       exit (1);
96     }
97   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
98   res = mpfr_strtofr (x, "NAN(abc%dEDF)__1256)Hello", &s, 10, MPFR_RNDN);
99   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "(abc%dEDF)__1256)Hello") )
100     {
101       printf ("Error for setting NAN (5)\n");
102       exit (1);
103     }
104   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
105   res = mpfr_strtofr (x, "NAN((abc))", &s, 10, MPFR_RNDN);
106   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "((abc))") )
107     {
108       printf ("Error for setting NAN (6)\n");
109       exit (1);
110     }
111   mpfr_set_ui (x, 0, MPFR_RNDN); /* make sure that x is modified */
112   res = mpfr_strtofr (x, "NAN()foo", &s, 10, MPFR_RNDN);
113   if (res != 0 || !mpfr_nan_p (x) || strcmp(s, "foo") )
114     {
115       printf ("Error for setting NAN (7)\n");
116       exit (1);
117     }
118 
119   /* Check infinity */
120   for (i = 0; i <= 0xff; i++)
121     {
122       char t[11] = "+@INFINITY";  /* not char *: this will be modified. */
123       char *p;
124       int base, j;
125 
126       /* Test all the case variants, assuming ASCII or similar.
127          The first letters are changed first, so that at i = 8,
128          the 2^3 = 8 "INF" case variants have been tested, and
129          they don't need to be tested again for i > 8. */
130       for (j = 0; j < 8; j++)
131         if ((i >> j) % 2 != 0)
132           t[j+2] += 'a' - 'A';
133 
134       /* Test "INFINITY", "+INFINITY", "-INFINITY",
135               "INF", "+INF", "-INF",
136               "@INF@", "+@INF@", "-@INF@",
137          up to case changes. */
138       for (j = 0; j < 9; j++)
139         {
140           if (j == 3)
141             {
142               /* At i = 8, we have tested all the "INF" case variants. */
143               if (i >= 8)
144                 break;
145               t[5] = '\0';
146             }
147           if (j == 6)
148             {
149               t[1] = '@';
150               t[5] = '@';
151               t[6] = '\0';
152             }
153           if (j % 3 == 1)
154             t[j != 7] = '+';
155           if (j % 3 == 2)
156             t[j != 8] = '-';
157           p = t + (j % 3 == 0) + (j < 6);
158           base = randlimb () % (j < 6 ? 17 : 63);
159           if (base == 1)
160             base = 0;
161           res = mpfr_strtofr (x, p, &s, base, MPFR_RNDN);
162           if (res != 0 || !mpfr_inf_p (x) || *s != 0 ||
163               (j % 3 != 2 ? MPFR_IS_NEG (x) : MPFR_IS_POS (x)))
164             {
165               printf ("Error for setting \"%s\" in base %d\n s=\"%s\"\n x=",
166                       p, base, s);
167               mpfr_dump (x);
168               exit (1);
169             }
170         }
171     }
172   res = mpfr_strtofr (x, "INFANITY", &s, 8, MPFR_RNDN);
173   if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "ANITY"))
174     {
175       printf ("Error for setting INFINITY (2)\n s=%s\n x=", s);
176       mpfr_dump (x);
177       exit (1);
178     }
179   res = mpfr_strtofr (x, "@INF@*2", &s, 11, MPFR_RNDN);
180   if (res != 0 || !mpfr_inf_p (x) || strcmp(s, "*2"))
181     {
182       printf ("Error for setting INFINITY (3)\n s=%s\n x=", s);
183       mpfr_dump (x);
184       exit (1);
185     }
186 
187   /* Check Zero */
188   res = mpfr_strtofr (x, " 00000", &s, 11, MPFR_RNDN);
189   if (res != 0 || !mpfr_zero_p (x) || s[0] != 0)
190     {
191       printf ("Error for setting ZERO (1)\n s=%s\n x=", s);
192       mpfr_dump (x);
193       exit (1);
194     }
195 
196   /* Check base 62 */
197   res = mpfr_strtofr (x, "A", NULL, 62, MPFR_RNDN);
198   if (res != 0 || mpfr_cmp_ui (x, 10))
199     {
200       printf ("Error for setting 'A' in base 62\n x=");
201       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
202       putchar ('\n');
203       exit (1);
204     }
205   res = mpfr_strtofr (x, "a", NULL, 62, MPFR_RNDN);
206   if (res != 0 || mpfr_cmp_ui (x, 36))
207     {
208       printf ("Error for setting 'a' in base 62\n x=");
209       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
210       putchar ('\n');
211       exit (1);
212     }
213   res = mpfr_strtofr (x, "Z", NULL, 62, MPFR_RNDN);
214   if (res != 0 || mpfr_cmp_ui (x, 35))
215     {
216       printf ("Error for setting 'Z' in base 62\n x=");
217       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
218       putchar ('\n');
219       exit (1);
220     }
221   res = mpfr_strtofr (x, "z", NULL, 62, MPFR_RNDN);
222   if (res != 0 || mpfr_cmp_ui (x, 61))
223     {
224       printf ("Error for setting 'z' in base 62\n x=");
225       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
226       putchar ('\n');
227       exit (1);
228     }
229   res = mpfr_strtofr (x, "ZA", NULL, 62, MPFR_RNDN);
230   if (res != 0 || mpfr_cmp_ui (x, 2180))
231     {
232       printf ("Error for setting 'ZA' in base 62\n x=");
233       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
234       putchar ('\n');
235       exit (1);
236     }
237   res = mpfr_strtofr (x, "za", NULL, 62, MPFR_RNDN);
238   if (res != 0 || mpfr_cmp_ui (x, 3818))
239     {
240       printf ("Error for setting 'za' in base 62\n x=");
241       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
242       putchar ('\n');
243       exit (1);
244     }
245   res = mpfr_strtofr (x, "aZ", NULL, 62, MPFR_RNDN);
246   if (res != 0 || mpfr_cmp_ui (x, 2267))
247     {
248       printf ("Error for setting 'aZ' in base 62\n x=");
249       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
250       putchar ('\n');
251       exit (1);
252     }
253   res = mpfr_strtofr (x, "Az", NULL, 62, MPFR_RNDN);
254   if (res != 0 || mpfr_cmp_ui (x, 681))
255     {
256       printf ("Error for setting 'Az' in base 62\n x=");
257       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
258       putchar ('\n');
259       exit (1);
260     }
261 
262   /* Check base 60 */
263   res = mpfr_strtofr (x, "Aa", NULL, 60, MPFR_RNDN);
264   if (res != 0 || mpfr_cmp_ui (x, 636))
265     {
266       printf ("Error for setting 'Aa' in base 60\n x=");
267       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
268       putchar ('\n');
269       exit (1);
270     }
271   res = mpfr_strtofr (x, "Zz", &s, 60, MPFR_RNDN);
272   if (res != 0 || mpfr_cmp_ui (x, 35) || strcmp(s, "z") )
273     {
274       printf ("Error for setting 'Zz' in base 60\n x=");
275       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
276       putchar ('\n');
277       exit (1);
278     }
279 
280   /* Check base 61 */
281   res = mpfr_strtofr (x, "z", &s, 61, MPFR_RNDN);
282   if (res != 0 || mpfr_cmp_ui (x, 0) || strcmp(s, "z") )
283     {
284       printf ("Error for setting 'z' in base 61\n x=");
285       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
286       putchar ('\n');
287       exit (1);
288     }
289 
290   mpfr_clear (x);
291   mpfr_clear (y);
292 }
293 
294 /* The following RefTable has been generated by this following code */
295 #if 0
296 #define MAX_NUM 100
297 
298 int randomab (int a, int b)
299 {
300   return a + rand () % (b-a);
301 }
302 
303 int
304 main (void)
305 {
306   int i, base;
307   mpfr_t x;
308   mpfr_prec_t p;
309   mpfr_exp_t e;
310 
311   mpfr_init (x);
312   printf ("struct dymmy_test { \n"
313           " mpfr_prec_t prec; \n"
314           " int base; \n"
315           " const char *str; \n"
316           " const char *binstr; \n"
317           " } RefTable[] = { \n");
318   for (i = 0 ; i < MAX_NUM ; i++)
319     {
320       p = randomab(2, 180);
321       base = randomab (2, 30);
322       e = randomab (-1<<15, 1<<15);
323       mpfr_set_prec (x, p);
324       mpfr_urandomb (x, RANDS);
325       mpfr_mul_2si (x, x, e, MPFR_RNDN);
326       printf("{%lu, %d,\n\"", p, base);
327       mpfr_out_str (stdout, base, p, x, MPFR_RNDN);
328       printf ("\",\n\"");
329       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
330       printf ("\"}%c\n", i == MAX_NUM-1 ? ' ' : ',' );
331     }
332   printf("};\n");
333   mpfr_clear (x);
334 }
335 #endif
336 
337 static struct dymmy_test {
338  mpfr_prec_t prec;
339  int base;
340  const char *str;
341  const char *binstr;
342  } RefTable[] = {
343 {39, 20,
344 "1.1c9jeh9jg12d8iiggf26b8ce2cig24agai51d9@1445",
345 "1.00111010111010001110110001101011101011e6245"},
346 {119, 3,
347 "1.2210112120221020220021000020101121120011021202212101222000011110211211122222001001221110102220122021121021101010120101e-5655",
348 "1.1111101110011110001101011100011000011100001011011100010011010010001000000111001010000001110111010100011000110010000000e-8963"},
349 {166, 18,
350 "3.ecg67g31434b74d8hhbe2dbbb46g9546cae72cae0cfghfh00ed7gebe9ca63b47h08bgbdeb880a76dea12he31e1ccd67e9dh22a911b46h517b745169b2g43egg2e4eah820cdb2132d6a4f9c63505dd4a0dafbc@-5946",
351 "1.011110010000110011111011111100110110010110000010100001101111111000010000011111110101100000010110011001100000010001100101000001101000010010001011001011000110100011001e-24793"},
352 {139, 4,
353 "1.020302230021023320300300101212330121100031233000032101123133120221012000000000000000000000000000000000000000000000000000000000000000000000e11221",
354 "1.001000110010101100001001001011111000110000110000010001100110111100011001010000001101101111000000001110010001011011011111011000101001000110e22442"},
355 {126, 13,
356 "4.a3cb351c6c548a0475218519514c6c54366681447019ac70a387862c39c86546ab27608c9c2863328860aa2464288070a76c0773882728c5213a335289259@2897",
357 "1.01011010000001110001100001101111100111011010010111000011000101111011000100001010010100110111101001001001000000011100010000000e10722"},
358 {6, 26,
359 "1.j79f6@-1593",
360 "1.00000e-7487"},
361 {26, 18,
362 "3.5e99682hh310aa89hb2fb4h88@-5704",
363 "1.0110010100010101000101100e-23784"},
364 {12, 21,
365 "4.j7f3e2ccdfa@-3524",
366 "1.10110101011e-15477"},
367 {38, 28,
368 "o.agr0m367b9bmm76rplg7b53qlj7f02g717cab@6452",
369 "1.1001010011101100110100111000111010001e31021"},
370 {75, 17,
371 "4.00abd9gc99902e1cae2caa7647gcc029g01370e96d3f8e9g02f814d3ge5faa29d40b9db470@5487",
372 "1.11100000110101010111101001110001001010111111010100000100001010100111011101e22429"},
373 {91, 16,
374 "1.0a812a627160014a3bda1f00000000000000000000000000000000000000000000000000000000000000000000@7897",
375 "1.000010101000000100101010011000100111000101100000000000010100101000111011110110100001111100e31588"},
376 {154, 19,
377 "1.989279dda02a8ic15e936ahig3c695f6059a3i01b7d1ge6a418bf84gd87e36061hb2bi62ciagcgb9226fafea41d2ig1e2f0a10ea3i40d6dahf598bdbh372bdf5901gh276866804ah53b6338bi@5285",
378 "1.110101101101101111110010001011110001100000010100011101101001000100110100000011110111000011011101011110010100110101011011111100101101001100000101101000010e22450"},
379 {53, 2,
380 "1.0100010111100111001010000100011011111011011100110111e-20319",
381 "1.0100010111100111001010000100011011111011011100110111e-20319"},
382 {76, 3,
383 "2.101212121100222100012112101120011222102000021110201110000202111122221100001e1511",
384 "1.000110101010111000011001011111110000001001101001011011111110111111010000111e2396"},
385 {31, 9,
386 "1.171774371505084376877631528681e3258",
387 "1.110101101011111011111000110011e10327"},
388 {175, 8,
389 "4.506242760242070533035566017365410474451421355546570157251400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e3483",
390 "1.001010001100101000101111100000101000100001110001010110110000111011011101100000011110111101011000010001001111001001010011000100010111011011011001101011110000011011110101010011e10451"},
391 {103, 24,
392 "8.0hmlm3g183cj358fn4bimn5bie1l89k95m647474mm8jg5kh1c011gi0m7de9j7b48c595g1bki4n32kll7b882eg7klgga0h0gf11@4510",
393 "1.001000110101001101011010101001111010110100010100110101010101110000001011001101110110010111000101010111e20681"},
394 {12, 9,
395 "3.00221080453e2479",
396 "1.11000111010e7859"},
397 {86, 11,
398 "6.873680186953174a274754118026423965415553a088387303452447389287133a0956111602a5a085446@5035",
399 "1.0000000000110100010110000111010001010100101011000100101010010011101010000110011110001e17421"},
400 {68, 10,
401 "6.1617378719016284192718392572980535262609909598793237475124371481233e481",
402 "1.0110001011000101110010111101100101111110001100001011110011001101111e1600"},
403 {11, 15,
404 "5.ab10c18d45@907",
405 "1.0000101111e3546"},
406 {77, 26,
407 "6.e6kl84g6h30o3nfnj7fjjff4n1ee6e5iop76gabj23e7hgan9o6724domc7bp4hdll95g817519f@5114",
408 "1.1011000101111111111110011011101100000100101000001001100000001011010001001000e24040"},
409 {28, 27,
410 "d.odiqp9kgh84o8d2aoqg4c21hemi@3566",
411 "1.101001111001111111110011110e16959"},
412 {45, 14,
413 "7.cddc6295a576980adbc8c16111d6301bad3146a1143c@-6227",
414 "1.10000000110011000000101100110001011100010111e-23706"},
415 {54, 19,
416 "1.b6e67i2124hfga2g819g1d6527g2b603eg3cd8hhca9gecig8geg1@4248",
417 "1.11010100100010101101110110010100000010111010010101110e18045"},
418 {49, 20,
419 "1.jj68bj6idadg44figi10d2ji99g6ddi6c6ich96a5h86i529@-3149",
420 "1.001011111101100100001010001000011100000000101110e-13609"},
421 {171, 16,
422 "6.22cf0e566d8ff11359d70bd9200065cfd72600b12e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@5602",
423 "1.10001000101100111100001110010101100110110110001111111100010001001101011001110101110000101111011001001000000000000001100101110011111101011100100110000000001011000100101110e22410"},
424 {144, 14,
425 "1.425d9709b4c125651ab88bb1a0370c14270d067a9a74a612dad48d5c025531c175c1b905201d0d9773aa686c8249db9c0b841b10821791c02baa2525a4aa7571850439c2cc965cd@-3351",
426 "1.11100111110001001101010111010000101010011000111001101011000001011110101110011011100100111001101101111011001001101011001101001011011101101111011e-12759"},
427 {166, 6,
428 "3.324252232403440543134003140400220120040245215204322153511143504542403430152410543444455151104314552352030352125540101550151410414122051500201022252511512332523431554e8340",
429 "1.010101111101111101001001110010111110010000001111010101100110011011010110011001001100001111010101100000010111011111101110110111101110010001110001111000001010001111000e21560"},
430 {141, 24,
431 "2.i3c88lkm2958l9ncb9f85kk35namjli84clek5j6jjkli82kb9m4e4i2g39me63db2094cif80gcba8ie6l15ia0d667kn9i1f77bdak599e1ach0j05cdn8kf6c6kfd82j2k6hj2c4d@4281",
432 "1.10011100001010110111001000000000101011100010101011001010001101110100110111011000111101000001111101100000110100100010101011001100100011001011e19629"},
433 {84, 6,
434 "2.41022133512503223022555143021524424430350133500020112434301542311050052304150111243e982",
435 "1.11010001111111001010011100011000011100100111111010001111010010101001001000011100001e2539"},
436 {56, 9,
437 "1.5305472255016741401411184703518332515066156086511016413e2936",
438 "1.0111110010001101000000110101110000110101001011001100111e9307"},
439 {18, 8,
440 "3.63542400000000000e-599",
441 "1.11100111011000101e-1796"},
442 {111, 13,
443 "8.b693ac7a24679b98708a0057a6202c867bc146740ab1971b380756a24c99804b63436419239ba0510030b819933771a636c57c5747b883@-6160",
444 "1.01011011111110100101110010100100000110000011011101001110010110000011101110111111010111000011011101101001100100e-22792"},
445 {162, 16,
446 "4.f2abe958a313566adbf3169e55cdcff3785dbd5c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@382",
447 "1.00111100101010101111101001010110001010001100010011010101100110101011011011111100110001011010011110010101011100110111001111111100110111100001011101101111010101110e1530"},
448 {117, 23,
449 "2.4b6kk3ag3if217ih1hggkk69bmcecfil1cd38dijh35j8e6ckhd335a4gj7l05bedk19473i8449b1ajc3jd3ka95eceheh72lh2jh17jamlm1142gll@-3628",
450 "1.10010010001010001110011000010000011111011101111100110101100100101111101110010011101001111010100010001111110100101111e-16411"},
451 {179, 2,
452 "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203",
453 "1.1101101011111010101000110101010101101110001011011010101001110111011010011110001000000110101100010010001110010110011000000110001011111001011110100011101000110001001000110100100110e14203"},
454 {18, 27,
455 "4.ll743n2f654gh3154@-6039",
456 "1.01101001111010011e-28713"},
457 {178, 15,
458 "1.e5443105cad2d014b700c42aa3de854c4b95322420695d07db3564ec07473da83bde123b74c794139265a838ebeca745ad3dc97d7c356271ca935ea8e83306562c2a8edc6e886c1b6b2d3e17038379c33826526770985c068@821",
459 "1.011100001000101100111111111111000100110111110011101010001111011001111101111001010011100100100101100011101001000000101001010100011111001011001010011101101001000111111010101101011e3208"},
460 {161, 22,
461 "2.46ikji624bg042877h8g2jdki4ece6ede62841j7li843a4becdkkii86c54192jkefehikkb3kcb26ij1b3k9agfbb07dih88d6ej0ee0d63i8hedc7f0g0i9g7jf9gf6423j70h421bg5hf2bja9j0a432lb10@-5125",
462 "1.0111011000111110000010011100001100100110001011101001011110111010100000011100000010011101011100101100111100110000001101010101011110100011101111001011001111100000e-22854"},
463 {62, 19,
464 "7.bgd1g0886a6c3a9ee67cc7g3bgf718i98d90788idi5587358e660iffc0ic6@3257",
465 "1.0101100100001110000100010110100100000111110001111001011110100e13838"},
466 {127, 19,
467 "1.413bgf99eidba75ged25f7187080bce3h7ebdeghea4ig6c79g94di7b42a3e4cdi4ic6a53i71d2e4hdbe50ih0a0egf2fi469732131ig6g496bf7h8g3c86ie7h@-4465",
468 "1.001101111000011011100010010010010110111001001001110011110101111111000001110101111110001110010000110011111101000011000101111101e-18967"},
469 {17, 21,
470 "4.7d5b70gh4k0gj4fj@-116",
471 "1.1000100010000110e-508"},
472 {141, 13,
473 "2.2b4988c5cb57072a6a1a9c42224794a1cbc175a9bc673bb28aa045c3182b9396ca8bb8590969672b0239608a845a2c35c08908a58c2a83748c89241a6561422c7cc4866c8454@4358",
474 "1.10010110101000001000001001111001000100111110100010100110111011111011010010101000110101110000111100010000101101000110000000000001111110110011e16127"},
475 {39, 7,
476 "3.00350342452505221136410100232265245244e202",
477 "1.10011000111110011010100110101101010010e568"},
478 {119, 24,
479 "5.2aene587kc2d9a55mm8clhn4dn0a551de58b1fcli8e8hf1jlm7i0376dl5fhb2k8acka03077mnbn9d4dmi0641dce871c81g2b3ge76m3kngm4a9g5gh@-892",
480 "1.0111101010010100001001111110000000100101110010010111111100100101100001010010100110111000101100101010111000101111000010e-4088"},
481 {41, 14,
482 "5.c3dc5c49373d0c0075624931133022185bd08b16@-5294",
483 "1.0101011000010111111111000010100110011111e-20154"},
484 {41, 6,
485 "3.2411143454422033245255450304104450302500e2250",
486 "1.1110111101010101001001100000100011110111e5817"},
487 {17, 13,
488 "3.65789aa26aa273b1@-4490",
489 "1.1100011101010111e-16614"},
490 {10, 26,
491 "1.5p4hag1fl@6017",
492 "1.110010111e28282"},
493 {130, 11,
494 "2.606a72601843700427667823172635a47055021a0a68a99326875195a179483948407aa13726244552332114a1784aaa7239956521604460876871a65708458aa@-6285",
495 "1.110001001110111110110111000010101000110010011110010101100100001000101011010010000001000101000110111111110101000100000111100010100e-21742"},
496 {29, 20,
497 "j.4356d9b7i38i955jjj1j442501bj@163",
498 "1.1010101011110011100000100100e708"},
499 {140, 21,
500 "9.2f5k7aid6bj2b2g5bff29i73hk3a8d8g0i7ifa07hkb79g4hd3c7j6g4hjj2jbhai01gkje3h9g3gj3i34f0194kaed32iea9dcgcj8h7i1khdkf965c1ak97gf3h03fcab3ggi03fa@4864",
501 "1.0101011100011101000110101001010011111111010011000111111111100000011011100111010001100101100110001110001001100101001100110000011110100101101e21367"},
502 {133, 13,
503 "2.3721a9107307a71c75c07c83b70a25a9853619030b5bcb55101ca5c2060bca46c331b92b33aa957c3ac7c817335287c6917999c38c3806b6b5919623023ac52063bb@6602",
504 "1.011001101111100001100100110100010100010011100010111110110100100000000010011101001011000100000110011011101001010010011110111100010010e24431"},
505 {118, 2,
506 "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960",
507 "1.001010111011011000100010001110111000001100101000101101010001110110000111101110111011011101111100110010000101001001001e18960"},
508 {102, 23,
509 "l.26lhk42clcm9g940eihakhi32gb3331lld488cf1j4f73ge051bfl8gcmcg78gkjc2iibjf752eag0dee6dafa97k79jlh11j3270@-2160",
510 "1.01101011011000100101110111110001011000101101011001011111001101000110111010000010011111101110101100010e-9767"},
511 {156, 18,
512 "b.eb927dd4g48abee3cc2begehb9c3b8h83cae152db850ac2f3g816d6787825122c8h3aa3g8023h23000a8hg61065b3e367ac59ca373067730f96dd0d3b73b3c43fef91750b333gd497b8ce9228e7@5504",
513 "1.11000110111100011101100011001001110011101100011111010100101110010010010011111001100000011010011111111011001011111010001001011001110001100001101000000110000e22954"},
514 {158, 5,
515 "3.0112043214104344433122444210142004032004444213123303302023242414000243311324332203224340334422234000104132020124210141322013240010134130441413233111204013422e-10468",
516 "1.1001011000111111110100100101110011100001110100101001101110011001101001101011010010111010111111101010100011100010101100110111011101000110110100000111001100011e-24305"},
517 {7, 9,
518 "2.141540e-146",
519 "1.001111e-462"},
520 {111, 5,
521 "3.21233234110011204313222402442032333320324004133424222041314021020411320312421014434003440431230413141402230403e7641",
522 "1.10010000000101010000101010101011011010000100010010010000010110001111000111111111000110111001100101101110101101e17743"},
523 {76, 13,
524 "7.1c0861453a4ac156b6119ba7548251b5cb00b7c409c2bb8138214676468c9949676226013c1@4639",
525 "1.001000011000000011101101101010100010010001010111100110010101111110110010111e17169"},
526 {6, 25,
527 "c.aj660@-6978",
528 "1.11000e-32402"},
529 {156, 3,
530 "2.22101000022222000012110122210202211110020121210120112102122121111210000211020001020201202200011021211102012110220222110022001121011022011202000110120021012e-14744",
531 "1.11010001111000101111110000010011001101000100010010110011100100110001100111011101011111111100011111001100001111100101100000001000001100000000010010001011101e-23368"},
532 {7, 23,
533 "1.4hclk2@2148",
534 "1.110110e9716"},
535 {69, 11,
536 "2.77684920493191632416690544493465617a187218365952a6740034288687745a26@3263",
537 "1.01111000111000001111001110000110000110001111110011101100101111011100e11289"},
538 {146, 21,
539 "3.agg4d0dj636d526d4i8643ch5jee4ge2c3i46k121857dbedagd98cjifaf0fgc09ca739g2fkfbfh06i687kic2kb8c7i48gda57bb6d9bh81eh49h0d8e3i7ad2kgb1ek86b86g3589k27d@3562",
540 "1.0010111111111100101010101010001100110101010011011100001110111000101101001110001110010100000001010001000111010000010011110100010010101100101000001e15647"},
541 {20, 3,
542 "1.2000000021102111102e-16642",
543 "1.1011101011111110000e-26377"},
544 {68, 13,
545 "1.a43205b2164676727806614acc0398925569c3962a3ba419881a5c63b651aa3ab46@-618",
546 "1.1111011000001110010100111000110010110110011001110001100101011111000e-2287"},
547 {129, 4,
548 "2.22033002012102010122130132103000303000120122313322000222121000300000000000000000000000000000000000000000000000000000000000000000e13222",
549 "1.01010001111000010000110010010000100011010011100011110010011000000110011000000011000011010110111111010000000101010011001000000110e26445"},
550 {22, 6,
551 "1.420033001013011530142e11704",
552 "1.001000110010110110001e30255"},
553 {108, 6,
554 "1.03345424443433104422104400512453214240453335230205104304115343030341144544051005432030344054100542125304500e7375",
555 "1.00101101110001011101101111000010101011101000001111001110001101100000111100010101010101101100011110111010000e19064"},
556 {91, 27,
557 "2.ao077kf8oqoihn5pm6f5eqdcgnd2132d7p6n7di8ep82a1a9be99pm36g1emacbenaeiqphpgpdjhmm9ke3pn4pdea@-5482",
558 "1.111101100001000011101010001000000111000100100111110010101101110001101101101101101010111110e-26066"},
559 {96, 9,
560 "8.25805186310703506315505842015248775712246416686874260383701323213202658278523870037877823670166e-8134",
561 "1.11010111111000011100111001011010001110010001011101011101110101000101100100100010110011001010000e-25782"},
562 {161, 16,
563 "7.3a7627c1e42ef738698e292f0b81728c4b14fe8c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-3342",
564 "1.1100111010011101100010011111000001111001000010111011110111001110000110100110001110001010010010111100001011100000010111001010001100010010110001010011111110100011e-13366"},
565 {90, 3,
566 "2.10212200011211012002002221112120210222002020100202111000211012122020011102022112222021001e-3447",
567 "1.11100010111011011000101111110001000101000111110001100001010111101101011011110001000010001e-5463"},
568 {100, 27,
569 "a.f81hjjakdnc021op6ffh530ec8ige6n2fqc8f8j7ia7qelebgqkm4ic5ohh652hq1kgpag6pp0ldin6ce1fg6mj34077f5qc5oe@6576",
570 "1.011101001010010011110001100011111111010001110110100100101001010000101011101011110010010011111100000e31271"},
571 {152, 16,
572 "e.37ac48a0303f903c9d20883eddea4300d1190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000@-1388",
573 "1.1100011011110101100010010001010000000110000001111111001000000111100100111010010000010001000001111101101110111101010010000110000000011010001000110010000e-5549"},
574 {106, 20,
575 "1.3g2h7i2776d50gjibi937f8cdci3idecdeh3j2gba0j8d1ghgg3eg609ji55h5g7jeai1bii3a4f9jhjfij6jd1g3cg0f6024e252gc3e@6422",
576 "1.100110000101011010100111100110000000100101000110110011010010000101000100110010001110011110111100010000111e27755"},
577 {23, 17,
578 "9.f72e724454d1g0f60g93g6@-6563",
579 "1.0011100011110110010001e-26823"},
580 {98, 6,
581 "1.2444223304453415235424343034030405514010421403514410005234221430055051205523402412055242134042045e-8535",
582 "1.1101110011010001101001001111100101111010100111001011110001000010100101101110011011101100000111011e-22063"},
583 {4, 18,
584 "1.gec@-6711",
585 "1.100e-27984"},
586 {69, 24,
587 "8.d45gdfnhkhb7a20nj96dnggic83imhjne0cceldechn1m4e9fbd9db0ablngjf9n7810@6975",
588 "1.00100111111100101100110011110110110000110110110010100101011111000100e31983"},
589 {122, 8,
590 "4.0227760456667717717077553523466457265600000000000000000000000000000000000000000000000000000000000000000000000000000000000e-1767",
591 "1.0000001001011111111000010010111011011011111100111111100111100011111110110101110101001110011011010010111101011010111000000e-5299"},
592 {144, 23,
593 "8.b01c48dg20bek9a5k376clc501aecg92bdjaeji2dm9230i7j3k36jm50b0c5a0753i2b18534cji34bcl2li033cc534m52k2gbegc25a5g30lf4calag58026i5d7li61jg9digj5ceb1@-4456",
594 "1.00010000110011010111011011110111001101111001010110001101011100100101101110110000010011011111100000100110001001001111111011010110000000001111110e-20154"},
595 {111, 4,
596 "2.23100111310122202021232133233012212012232222323230133100000000000000000000000000000000000000000000000000000000e-10458",
597 "1.01011010000010101110100011010100010001001101110011111101111000110100110000110101110101010111011101100011111010e-20915"},
598 {117, 10,
599 "1.61207328685870427963864999744776917701013812304254540861834226053316419217753608451422967376154318603744156166920074e-6440",
600 "1.01100011000100111001100010000000110010100001001011111010100001101111100100101100111010100011101110001010011010010010e-21393"},
601 {106, 16,
602 "1.dd30a1d24091263243ca1c144f0000000000000000000000000000000000000000000000000000000000000000000000000000000@354",
603 "1.110111010011000010100001110100100100000010010001001001100011001001000011110010100001110000010100010011110e1416"},
604 {77, 14,
605 "4.90d6913ba57b149d8d85a58c311b4d537c10bd7d3c10d69c62bc08d32269760126a58115a105@-7311",
606 "1.1001000000111100000111001001011000110101001111100001100111010100010000011111e-27834"},
607 {8, 4,
608 "3.2230000e15197",
609 "1.1101011e30395"},
610 {81, 24,
611 "1.84ni25h558abmhg2dk7bl2jbbmkf4i8i2bemc5cgmk9jf301c00k24271m9h7mgm4301be1lnldn4364@2573",
612 "1.01110010011000110110100101011001011111101111101100010110101101011101100001000010e11797"},
613 {94, 2,
614 "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427",
615 "1.010010010101111001001011111111100100011110110100010001101111111100100101101100110101001011111e32427"},
616 {77, 21,
617 "1.87e4k9df85g50ead6fcj4h86820ikdjdjg93d90ca406g470hhkh7ciaba1aggg753g36553ebh5@2538",
618 "1.0010001100011000111010000010011001010011000000100101010001100000111101000111e11148"},
619 {80, 17,
620 "1.923gga999230g94fce02efg753ce001045a35e0264c9c2cb17850e32484fc3526dcg38ed874g5f2@3392",
621 "1.0011100111101001001101111001110100001100111110011110110001100110101010111001110e13865"},
622 {99, 7,
623 "4.53646362336126606650465342500160461331562113222506144210636341332436342025203333264316511653025011e-5540",
624 "1.01101101111001001100001101101101010011001001100110111000010000101000011001001001101000011101011001e-15551"},
625 {119, 20,
626 "1.c8966iabcf4de94ad15f9e83j407i3he7fch54h5jh0g5d74e06c057gg72a107didj8d1j8geibbfec5j36c3fgd5e12edjb9g10j7c9i03f33hi80ce0@7153",
627 "1.0101110101100011110001001110100110011000100000001001000110111110011111100011111010011101011111101101010011110111110100e30915"},
628 {93, 13,
629 "2.c749cb562c3a758b1a21a650666a4c6c53c76ca58a1a75a0358c9ac3866887972b3551a03aa6c150856531258508@193",
630 "1.10101111101001011010111101100100111110011111010110111101100100010011001001100011110100111110e715"},
631 {145, 14,
632 "1.c61614b64261d22c62cb9d16163ca4d144ac23351b708506b3b610b1b67b764ca974448d7a2c6515a6bc97503d4b2a530c75b2b677a464c6629c69b6c3d7860d7749b4b653c434d5@2050",
633 "1.111111100001101111100011001111100010010000101000011110000001110100111001011010100001001010111111010001111101000110011000011101110110001001100101e7805"},
634 {159, 23,
635 "4.bj9l07l0215e7l6lf1dkf62i056l37jaa0gdih717656f1kk1a77883jf99jg31le43em76bmcg4lddl782ihkla0m392886d8lm67d6c3a1l4j12kg0l1k52ee77lmk0gech11g8jeei680k85bi460c7el17@-1539",
636 "1.01010100110100100101100001011100000001100011110001001101000010000001000010000110000110010001110100001101011101101001001101101111001101101111101001010010010100e-6960"},
637 {24, 25,
638 "g.m749al09kflg5b42jnn4a7b@-2820",
639 "1.01010010101011010111011e-13092"},
640 {88, 18,
641 "3.5ed0gad0bhhb7aa9ge2ad1dhcg6833f3e068936hghf23gd2aa69f13539f15hfce50aa64achfee49bfg7249g@-4058",
642 "1.001000010110011011000101100000101111101001100011101101001111110111000010010110010001100e-16920"}
643 };
644 
645 static void
646 check_reftable (void)
647 {
648   int i, base;
649   mpfr_t x, y;
650   mpfr_prec_t p;
651   char *s;
652 
653   mpfr_init2 (x, 200);
654   mpfr_init2 (y, 200);
655   for (i = 0 ; i < numberof (RefTable) ; i++)
656     {
657       base = RefTable[i].base;
658       p    = RefTable[i].prec;
659       mpfr_set_prec (x, p);
660       mpfr_set_prec (y, p);
661       mpfr_set_str_binary (x, RefTable[i].binstr);
662       mpfr_strtofr (y, RefTable[i].str, &s, base, MPFR_RNDN);
663       if (s == NULL || *s != 0)
664         {
665           printf ("strtofr didn't parse entire input for i=%d:\n"
666                   " Str=%s", i, RefTable[i].str);
667           exit (1);
668         }
669       if (mpfr_cmp (x, y))
670         {
671           printf ("Results differ between strtofr and set_binary for i=%d:\n"
672                   " Set binary gives: ", i);
673           mpfr_dump (x);
674           printf (" strtofr    gives: ");
675           mpfr_dump (y);
676           printf (" setstr     gives: ");
677           mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
678           mpfr_dump (x);
679           mpfr_set_prec (x, 2*p);
680           mpfr_set_str (x, RefTable[i].str, base, MPFR_RNDN);
681           printf (" setstr ++  gives: ");
682           mpfr_dump (x);
683           exit (1);
684         }
685     }
686   mpfr_clear (y);
687   mpfr_clear (x);
688 }
689 
690 static void
691 check_parse (void)
692 {
693   mpfr_t x;
694   char *s;
695   int res;
696 
697   mpfr_init (x);
698 
699   /* Invalid data */
700   mpfr_set_si (x, -1, MPFR_RNDN);
701   res = mpfr_strtofr (x, "  invalid", NULL, 10, MPFR_RNDN);
702   if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x))
703     {
704       printf ("Failed parsing '  invalid' (1)\n X=");
705       mpfr_dump (x);
706       exit (1);
707     }
708   MPFR_ASSERTN (res == 0);
709   mpfr_set_si (x, -1, MPFR_RNDN);
710   res = mpfr_strtofr (x, "  invalid", &s, 0, MPFR_RNDN);
711   if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x) || strcmp (s, "  invalid"))
712     {
713       printf ("Failed parsing '  invalid' (2)\n S=%s\n X=", s);
714       mpfr_dump (x);
715       exit (1);
716     }
717   MPFR_ASSERTN (res == 0);
718   /* Check if it stops correctly */
719   mpfr_strtofr (x, "15*x", &s, 10, MPFR_RNDN);
720   if (mpfr_cmp_ui (x, 15) || strcmp (s, "*x"))
721     {
722       printf ("Failed parsing '15*x'\n S=%s\n X=", s);
723       mpfr_dump (x);
724       exit (1);
725     }
726   /* Check for leading spaces */
727   mpfr_strtofr (x, "  1.5E-10 *x^2", &s, 10, MPFR_RNDN);
728   if (mpfr_cmp_str1 (x, "1.5E-10") || strcmp (s, " *x^2"))
729     {
730       printf ("Failed parsing '1.5E-10*x^2'\n S=%s\n X=", s);
731       mpfr_dump (x);
732       exit (1);
733     }
734   /* Check for leading sign */
735   mpfr_strtofr (x, "  +17.5E-42E ", &s, 10, MPFR_RNDN);
736   if (mpfr_cmp_str1 (x, "17.5E-42") || strcmp (s, "E "))
737     {
738       printf ("Failed parsing '+17.5E-42E '\n S=%s\n X=", s);
739       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
740       exit (1);
741     }
742   mpfr_strtofr (x, "-17.5E+42E\n", &s, 10, MPFR_RNDN);
743   if (mpfr_cmp_str1 (x, "-17.5E42") || strcmp (s, "E\n"))
744     {
745       printf ("Failed parsing '-17.5E+42\\n'\n S=%s\n X=", s);
746       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
747       exit (1);
748     }
749   /* P form */
750   mpfr_strtofr (x, "0x42P17", &s, 16, MPFR_RNDN);
751   if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
752     {
753       printf ("Failed parsing '0x42P17' (base = 16)\n S='%s'\n X=", s);
754       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
755       exit (1);
756     }
757   mpfr_strtofr (x, "-0X42p17", &s, 16, MPFR_RNDN);
758   if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
759     {
760       printf ("Failed parsing '-0x42p17' (base = 16)\n S='%s'\n X=", s);
761       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
762       exit (1);
763     }
764   mpfr_strtofr (x, "42p17", &s, 16, MPFR_RNDN);
765   if (mpfr_cmp_str (x, "8650752", 10, MPFR_RNDN) || *s != 0)
766     {
767       printf ("Failed parsing '42p17' (base = 16)\n S='%s'\n X=", s);
768       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
769       exit (1);
770     }
771   mpfr_strtofr (x, "-42P17", &s, 16, MPFR_RNDN);
772   if (mpfr_cmp_str (x, "-8650752", 10, MPFR_RNDN) || *s != 0)
773     {
774       printf ("Failed parsing '-42P17' (base = 16)\n S='%s'\n X=", s);
775       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
776       exit (1);
777     }
778   mpfr_strtofr (x, "0b1001P17", &s, 2, MPFR_RNDN);
779   if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
780     {
781       printf ("Failed parsing '0b1001P17' (base = 2)\n S='%s'\n X=", s);
782       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
783       exit (1);
784     }
785   mpfr_strtofr (x, "-0B1001p17", &s, 2, MPFR_RNDN);
786   if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
787     {
788       printf ("Failed parsing '-0B1001p17' (base = 2)\n S='%s'\n X=", s);
789       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
790       exit (1);
791     }
792   mpfr_strtofr (x, "1001p17", &s, 2, MPFR_RNDN);
793   if (mpfr_cmp_str (x, "1179648", 10, MPFR_RNDN) || *s != 0)
794     {
795       printf ("Failed parsing '1001p17' (base = 2)\n S='%s'\n X=", s);
796       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
797       exit (1);
798     }
799   mpfr_strtofr (x, "-1001P17", &s, 2, MPFR_RNDN);
800   if (mpfr_cmp_str (x, "-1179648", 10, MPFR_RNDN) || *s != 0)
801     {
802       printf ("Failed parsing '-1001P17' (base = 2)\n S='%s'\n X=", s);
803       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
804       exit (1);
805     }
806   /* Check for auto-detection of the base */
807   mpfr_strtofr (x, "+0x42P17", &s, 0, MPFR_RNDN);
808   if (mpfr_cmp_str (x, "42P17", 16, MPFR_RNDN) || *s != 0)
809     {
810       printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
811       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
812       exit (1);
813     }
814   mpfr_strtofr (x, "-42E17", &s, 0, MPFR_RNDN);
815   if (mpfr_cmp_str (x, "-42E17", 10, MPFR_RNDN) || *s != 0)
816     {
817       printf ("Failed parsing '-42E17'\n S=%s\n X=", s);
818       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
819       exit (1);
820     }
821   mpfr_strtofr (x, "-42P17", &s, 0, MPFR_RNDN);
822   if (mpfr_cmp_str (x, "-42", 10, MPFR_RNDN) || strcmp (s, "P17"))
823     {
824       printf ("Failed parsing '-42P17' (base = 0)\n S='%s'\n X=", s);
825       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
826       exit (1);
827     }
828   mpfr_strtofr (x, " 0b0101.011@42", &s, 0, MPFR_RNDN);
829   if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
830     {
831       printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
832       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
833       exit (1);
834     }
835   mpfr_strtofr (x, " 0b0101.011P42", &s, 0, MPFR_RNDN);
836   if (mpfr_cmp_str (x, "0101.011@42", 2, MPFR_RNDN) || *s != 0)
837     {
838       printf ("Failed parsing '0101.011@42'\n S=%s\n X=", s);
839       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
840       exit (1);
841     }
842   mpfr_strtofr (x, "+0x42@17", &s, 0, MPFR_RNDN);
843   if (mpfr_cmp_str (x, "4.2@18", 16, MPFR_RNDN) || *s != 0)
844     {
845       printf ("Failed parsing '+0x42P17'\n S=%s\n X=", s);
846       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
847       exit (1);
848     }
849 
850 
851   /* Check for space inside the mantissa */
852   mpfr_strtofr (x, "+0x4 2@17", &s, 0, MPFR_RNDN);
853   if (mpfr_cmp_ui (x, 4) || strcmp(s," 2@17"))
854     {
855       printf ("Failed parsing '+0x4 2@17'\n S=%s\n X=", s);
856       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
857       exit (1);
858     }
859   mpfr_strtofr (x, "+0x42 P17", &s, 0, MPFR_RNDN);
860   if (mpfr_cmp_ui (x, 0x42) || strcmp(s," P17"))
861     {
862       printf ("Failed parsing '+0x42 P17'\n S=%s\n X=", s);
863       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
864       exit (1);
865     }
866   /* Space between mantissa and exponent */
867   mpfr_strtofr (x, " -0b0101P 17", &s, 0, MPFR_RNDN);
868   if (mpfr_cmp_si (x, -5) || strcmp(s,"P 17"))
869     {
870       printf ("Failed parsing '-0b0101P 17'\n S=%s\n X=", s);
871       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
872       exit (1);
873     }
874   /* Check for Invalid exponent. */
875   mpfr_strtofr (x, " -0b0101PF17", &s, 0, MPFR_RNDN);
876   if (mpfr_cmp_si (x, -5) || strcmp(s,"PF17"))
877     {
878       printf ("Failed parsing '-0b0101PF17'\n S=%s\n X=", s);
879       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
880       exit (1);
881     }
882   /* At least one digit in the mantissa. */
883   mpfr_strtofr (x, " .E10", &s, 0, MPFR_RNDN);
884   if (strcmp(s," .E10"))
885     {
886       printf ("Failed parsing ' .E10'\n S=%s\n X=", s);
887       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
888       exit (1);
889     }
890   /* Check 2 '.': 2.3.4   */
891   mpfr_strtofr (x, "-1.2.3E4", &s, 0, MPFR_RNDN);
892   if (mpfr_cmp_str1 (x, "-1.2") || strcmp(s,".3E4"))
893     {
894       printf ("Failed parsing '-1.2.3E4'\n S=%s\n X=", s);
895       mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); putchar ('\n');
896       exit (1);
897     }
898   /* Check for 0x and 0b */
899   mpfr_strtofr (x, "  0xG", &s, 0, MPFR_RNDN);
900   if (mpfr_cmp_ui (x, 0) || strcmp(s,"xG"))
901     {
902       printf ("Failed parsing '  0xG'\n S=%s\n X=", s);
903       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
904       exit (1);
905     }
906   mpfr_strtofr (x, "  0b2", &s, 0, MPFR_RNDN);
907   if (mpfr_cmp_ui (x, 0) || strcmp(s,"b2"))
908     {
909       printf ("Failed parsing '  0b2'\n S=%s\n X=", s);
910       mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); putchar ('\n');
911       exit (1);
912     }
913   mpfr_strtofr (x, "-0x.23@2Z33", &s, 0, MPFR_RNDN);
914   if (mpfr_cmp_si (x, -0x23) || strcmp(s,"Z33"))
915     {
916       printf ("Failed parsing '-0x.23@2Z33'\n S=%s\n X=", s);
917       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
918       exit (1);
919     }
920   mpfr_strtofr (x, "  0x", &s, 0, MPFR_RNDN);
921   if (mpfr_cmp_ui (x, 0) || strcmp(s,"x"))
922     {
923       printf ("Failed parsing '  0x'\n S=%s\n X=", s);
924       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
925       exit (1);
926     }
927 
928   mpfr_clear (x);
929 }
930 
931 static void
932 check_overflow (void)
933 {
934   mpfr_t x;
935   char *s;
936 
937   mpfr_init (x);
938 
939   /* Huge overflow */
940   mpfr_strtofr (x, "123456789E2147483646", &s, 0, MPFR_RNDN);
941   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
942     {
943       printf ("Check overflow failed (1) with:\n s=%s\n x=", s);
944       mpfr_dump (x);
945       exit (1);
946     }
947   mpfr_strtofr (x, "123456789E9223372036854775807", &s, 0, MPFR_RNDN);
948   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
949     {
950       printf ("Check overflow failed (2) with:\n s='%s'\n x=", s);
951       mpfr_dump (x);
952 #if defined(__GNUC__)
953       printf ("This failure is triggered by GCC bug 86554:\n"
954               "  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86554\n"
955               "  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87276 "
956               "(about this test)\nWorkaround: disable code hoisting "
957               "with -fno-code-hoisting in CFLAGS.\n");
958       /* Note: In Debian, this error is obtained with gcc-snapshot from
959          20180908-1 to 20181127-1. With gcc-snapshot from 20181209-1 to
960          20190102-1 (at least), the MPFR build no longer seems affected
961          in general, but using --with-gmp-build=... together with
962          --enable-assert still triggers this failure. This bug has been
963          fixed in the GCC trunk rev 267725, thus the future gcc-snapshot
964          versions should no longer have this bug. */
965 #endif
966       exit (1);
967     }
968   mpfr_strtofr (x, "123456789E170141183460469231731687303715884105728",
969                 &s, 0, MPFR_RNDN);
970   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
971     {
972       printf ("Check overflow failed (3) with:\n s=%s\n x=", s);
973       mpfr_dump (x);
974       exit (1);
975     }
976 
977   /* Limit overflow */
978   mpfr_strtofr (x, "12E2147483646", &s, 0, MPFR_RNDN);
979   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x) )
980     {
981       printf ("Check overflow failed (4) with:\n s=%s\n x=", s);
982       mpfr_dump (x);
983       exit (1);
984     }
985   mpfr_strtofr (x, "12E2147483645", &s, 0, MPFR_RNDN);
986   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
987     {
988       printf ("Check overflow failed (5) with:\n s=%s\n x=", s);
989       mpfr_dump (x);
990       exit (1);
991     }
992   mpfr_strtofr (x, "0123456789ABCDEF@2147483640", &s, 16, MPFR_RNDN);
993   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
994     {
995       printf ("Check overflow failed (6) with:\n s=%s\n x=", s);
996       mpfr_dump (x);
997       exit (1);
998     }
999   mpfr_strtofr (x, "0123456789ABCDEF@540000000", &s, 16, MPFR_RNDN);
1000   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
1001     {
1002       printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
1003       mpfr_dump (x);
1004       exit (1);
1005     }
1006   mpfr_strtofr (x, "1@2305843009213693951", &s, 16, MPFR_RNDN);
1007   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
1008     {
1009       printf ("Check overflow failed (8) with:\n s=%s\n x=", s);
1010       mpfr_dump (x);
1011       exit (1);
1012     }
1013   mpfr_strtofr (x, "1@2305843009213693951", &s, 17, MPFR_RNDN);
1014   if (s[0] != 0 || !MPFR_IS_INF (x) || !MPFR_IS_POS (x))
1015     {
1016       printf ("Check overflow failed (9) with:\n s=%s\n x=", s);
1017       mpfr_dump (x);
1018       exit (1);
1019     }
1020 
1021   /* Check underflow */
1022   mpfr_strtofr (x, "123456789E-2147483646", &s, 0, MPFR_RNDN);
1023   if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
1024     {
1025       printf ("Check underflow failed (1) with:\n s=%s\n x=", s);
1026       mpfr_dump (x);
1027       exit (1);
1028     }
1029   mpfr_strtofr (x, "123456789E-9223372036854775807", &s, 0, MPFR_RNDN);
1030   if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
1031     {
1032       printf ("Check underflow failed (2) with:\n s='%s'\n x=", s);
1033       mpfr_dump (x);
1034       exit (1);
1035     }
1036   mpfr_strtofr (x, "-123456789E-170141183460469231731687303715884105728",
1037                 &s, 0, MPFR_RNDN);
1038   if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_NEG (x) )
1039     {
1040       printf ("Check underflow failed (3) with:\n s=%s\n x=", s);
1041       mpfr_dump (x);
1042       exit (1);
1043     }
1044   mpfr_strtofr (x, "0123456789ABCDEF@-540000000", &s, 16, MPFR_RNDN);
1045   if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x))
1046     {
1047       printf ("Check overflow failed (7) with:\n s=%s\n x=", s);
1048       mpfr_dump (x);
1049       exit (1);
1050     }
1051   mpfr_strtofr (x, "1@-2305843009213693952", &s, 16, MPFR_RNDN);
1052   if (s[0] != 0 || !MPFR_IS_ZERO (x) || !MPFR_IS_POS (x) )
1053     {
1054       printf ("Check underflow failed (8) with:\n s='%s'\n x=", s);
1055       mpfr_dump (x);
1056       exit (1);
1057     }
1058 
1059   mpfr_clear (x);
1060 }
1061 
1062 static void
1063 check_retval (void)
1064 {
1065   mpfr_t x;
1066   int res;
1067 
1068   mpfr_init2 (x, 10);
1069 
1070   res = mpfr_strtofr (x, "01011000111", NULL, 2, MPFR_RNDN);
1071   MPFR_ASSERTN (res == 0);
1072   res = mpfr_strtofr (x, "11011000111", NULL, 2, MPFR_RNDN);
1073   MPFR_ASSERTN (res > 0);
1074   res = mpfr_strtofr (x, "110110001101", NULL, 2, MPFR_RNDN);
1075   MPFR_ASSERTN (res < 0);
1076 
1077   mpfr_clear (x);
1078 }
1079 
1080 /* Bug found by Christoph Lauter (in mpfr_set_str). */
1081 static struct bug20081025_test {
1082   mpfr_rnd_t rnd;
1083   int inexact;
1084   const char *str;
1085   const char *binstr;
1086 } Bug20081028Table[] = {
1087   {MPFR_RNDN, -1, "1.00000000000000000006", "1"},
1088   {MPFR_RNDZ, -1, "1.00000000000000000006", "1"},
1089   {MPFR_RNDU, +1, "1.00000000000000000006",
1090    "10000000000000000000000000000001e-31"},
1091   {MPFR_RNDD, -1, "1.00000000000000000006", "1"},
1092 
1093 
1094   {MPFR_RNDN, +1, "-1.00000000000000000006", "-1"},
1095   {MPFR_RNDZ, +1, "-1.00000000000000000006", "-1"},
1096   {MPFR_RNDU, +1, "-1.00000000000000000006", "-1"},
1097   {MPFR_RNDD, -1, "-1.00000000000000000006",
1098    "-10000000000000000000000000000001e-31"},
1099 
1100   {MPFR_RNDN, +1, "0.999999999999999999999999999999999999999999999", "1"},
1101   {MPFR_RNDZ, -1, "0.999999999999999999999999999999999999999999999",
1102    "11111111111111111111111111111111e-32"},
1103   {MPFR_RNDU, +1, "0.999999999999999999999999999999999999999999999", "1"},
1104   {MPFR_RNDD, -1, "0.999999999999999999999999999999999999999999999",
1105    "11111111111111111111111111111111e-32"},
1106 
1107   {MPFR_RNDN, -1, "-0.999999999999999999999999999999999999999999999", "-1"},
1108   {MPFR_RNDZ, +1, "-0.999999999999999999999999999999999999999999999",
1109    "-11111111111111111111111111111111e-32"},
1110   {MPFR_RNDU, +1, "-0.999999999999999999999999999999999999999999999",
1111    "-11111111111111111111111111111111e-32"},
1112   {MPFR_RNDD, -1, "-0.999999999999999999999999999999999999999999999", "-1"}
1113 };
1114 
1115 static void
1116 bug20081028 (void)
1117 {
1118   int i;
1119   int inexact, res;
1120   mpfr_rnd_t rnd;
1121   mpfr_t x, y;
1122   char *s;
1123 
1124   mpfr_init2 (x, 32);
1125   mpfr_init2 (y, 32);
1126   for (i = 0 ; i < numberof (Bug20081028Table) ; i++)
1127     {
1128       rnd     = Bug20081028Table[i].rnd;
1129       inexact = Bug20081028Table[i].inexact;
1130       mpfr_set_str_binary (x, Bug20081028Table[i].binstr);
1131       res = mpfr_strtofr (y, Bug20081028Table[i].str, &s, 10, rnd);
1132       if (s == NULL || *s != 0)
1133         {
1134           printf ("Error in Bug20081028: strtofr didn't parse entire input\n"
1135                   "for (i=%d) Str=\"%s\"", i, Bug20081028Table[i].str);
1136           exit (1);
1137         }
1138       if (! SAME_SIGN (res, inexact))
1139         {
1140           printf ("Error in Bug20081028: expected %s ternary value, "
1141                   "got %d\nfor (i=%d) Rnd=%s Str=\"%s\"\n Set binary gives: ",
1142                   inexact > 0 ? "positive" : "negative",
1143                   res, i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
1144           mpfr_dump (x);
1145           printf (" strtofr    gives: ");
1146           mpfr_dump (y);
1147           exit (1);
1148         }
1149       if (mpfr_cmp (x, y))
1150         {
1151           printf ("Error in Bug20081028: Results differ between strtofr and "
1152                   "set_binary\nfor (i=%d) Rnd=%s Str=\"%s\"\n"
1153                   " Set binary gives: ",
1154                   i, mpfr_print_rnd_mode(rnd), Bug20081028Table[i].str);
1155           mpfr_dump (x);
1156           printf (" strtofr    gives: ");
1157           mpfr_dump (y);
1158           exit (1);
1159         }
1160     }
1161   mpfr_clear (y);
1162   mpfr_clear (x);
1163 }
1164 
1165 /* check that 1.23e is correctly parsed, cf
1166    https://gmplib.org/list-archives/gmp-bugs/2010-March/001898.html */
1167 static void
1168 test20100310 (void)
1169 {
1170   mpfr_t x, y;
1171   char str[] = "1.23e", *endptr;
1172 
1173   mpfr_init2 (x, 53);
1174   mpfr_init2 (y, 53);
1175   mpfr_strtofr (x, str, &endptr, 10, MPFR_RNDN);
1176   mpfr_strtofr (y, "1.23", NULL, 10, MPFR_RNDN);
1177   if (mpfr_cmp (x, y) != 0)
1178     {
1179       printf ("x <> y in test20100310\n");
1180       exit (1);
1181     }
1182   if (endptr != str + 4) /* strtofr should take into account '1.23',
1183                             not '1.23e' */
1184     {
1185       printf ("endptr <> str + 4 in test20100310\n");
1186       exit (1);
1187     }
1188   mpfr_clear (x);
1189   mpfr_clear (y);
1190 }
1191 
1192 /* From a bug reported by Joseph S. Myers
1193    https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html */
1194 static void
1195 bug20120814 (void)
1196 {
1197   mpfr_exp_t emin = -30, e;
1198   mpfr_t x, y;
1199   int r;
1200   char s[64], *p;
1201 
1202   mpfr_init2 (x, 2);
1203   mpfr_set_ui_2exp (x, 3, emin - 2, MPFR_RNDN);
1204   mpfr_get_str (s + 1, &e, 10, 19, x, MPFR_RNDD);
1205   s[0] = s[1];
1206   s[1] = '.';
1207   for (p = s; *p != 0; p++) ;
1208   *p = 'e';
1209   sprintf (p + 1, "%d", (int) e - 1);
1210 
1211   mpfr_init2 (y, 4);
1212   r = mpfr_strtofr (y, s, NULL, 0, MPFR_RNDN);
1213   if (r <= 0 || ! mpfr_equal_p (x, y))
1214     {
1215       printf ("Error in bug20120814\n");
1216       printf ("mpfr_strtofr failed on string \"%s\"\n", s);
1217       printf ("Expected inex > 0 and y = 0.1100E%d\n", (int) emin);
1218       printf ("Got inex = %-6d and y = ", r);
1219       mpfr_dump (y);
1220       exit (1);
1221     }
1222 
1223   mpfr_clear (x);
1224   mpfr_clear (y);
1225 }
1226 
1227 static void
1228 bug20120829 (void)
1229 {
1230   mpfr_t x1, x2, e;
1231   int inex1, inex2, i, r;
1232   char s[48] = "1e-1";
1233 
1234   mpfr_init2 (e, 128);
1235   mpfr_inits2 (4, x1, x2, (mpfr_ptr) 0);
1236 
1237   inex1 = mpfr_set_si (e, -1, MPFR_RNDN);
1238   MPFR_ASSERTN (inex1 == 0);
1239 
1240   for (i = 1; i <= sizeof(s) - 5; i++)
1241     {
1242       s[3+i] = '0';
1243       s[4+i] = 0;
1244       inex1 = mpfr_mul_ui (e, e, 10, MPFR_RNDN);
1245       MPFR_ASSERTN (inex1 == 0);
1246       RND_LOOP_NO_RNDF (r)
1247         {
1248           mpfr_rnd_t rnd = (mpfr_rnd_t) r;
1249 
1250           inex1 = mpfr_exp10 (x1, e, rnd);
1251           inex1 = VSIGN (inex1);
1252           inex2 = mpfr_strtofr (x2, s, NULL, 0, rnd);
1253           inex2 = VSIGN (inex2);
1254           /* On 32-bit machines, for i = 7, r8389, r8391 and r8394 do:
1255              strtofr.c:...: MPFR assertion failed: cy == 0
1256              r8396 is OK.
1257              On 64-bit machines, for i = 15,
1258              r8389 does: strtofr.c:678: MPFR assertion failed: err < (64 - 0)
1259              r8391 does: strtofr.c:680: MPFR assertion failed: h < ysize
1260              r8394 and r8396 are OK.
1261           */
1262           if (! mpfr_equal_p (x1, x2) || inex1 != inex2)
1263             {
1264               printf ("Error in bug20120829 for i = %d, rnd = %s\n",
1265                       i, mpfr_print_rnd_mode (rnd));
1266               printf ("Expected inex = %d, x = ", inex1);
1267               mpfr_dump (x1);
1268               printf ("Got      inex = %d, x = ", inex2);
1269               mpfr_dump (x2);
1270               exit (1);
1271             }
1272         }
1273     }
1274 
1275   mpfr_clears (e, x1, x2, (mpfr_ptr) 0);
1276 }
1277 
1278 /* https://sympa.inria.fr/sympa/arc/mpfr/2016-12/msg00043.html
1279    mpfr_strtofr can return an incorrect ternary value.
1280    Note: As a consequence, the value can also be incorrect if the current
1281    exponent range is not the maximum one (since the ternary value is used
1282    to resolve double rounding in mpfr_check_range); this can happen only
1283    if the value is a midpoint between 0 and the minimum positive number
1284    or the opposite. */
1285 static void
1286 bug20161217 (void)
1287 {
1288   mpfr_t fp, z;
1289   static const char * num = "0.1387778780781445675529539585113525390625e31";
1290   /* The above number is 5^47/2^9. */
1291   int inex;
1292 
1293   mpfr_init2 (fp, 110);
1294   mpfr_init2 (z, 110);
1295 
1296   inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN);
1297   MPFR_ASSERTN(inex == 0);
1298   mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001101E-9");
1299   MPFR_ASSERTN(mpfr_equal_p (fp, z));
1300 
1301   /* try with 109 bits */
1302   mpfr_set_prec (fp, 109);
1303   inex = mpfr_strtofr (fp, num, NULL, 10, MPFR_RNDN);
1304   MPFR_ASSERTN(inex < 0);
1305   mpfr_set_str_binary (z, "10001100001000010011110110011101101001010000001011011110010001010100010100100110111101000010001011001100001100E-9");
1306   MPFR_ASSERTN(mpfr_equal_p (fp, z));
1307 
1308   mpfr_clear (fp);
1309   mpfr_clear (z);
1310 }
1311 
1312 /* check bug in MPFR 3.1.5 is fixed: cf
1313    https://sympa.inria.fr/sympa/arc/mpfr/2017-03/msg00009.html
1314    Note: same bug as bug20161217. See also the comments of bug20161217;
1315    here, this is a case where the value is incorrect. */
1316 static void
1317 bug20170308 (void)
1318 {
1319   mpfr_exp_t emin;
1320    /* the following is slightly larger than 2^-1075, thus should be rounded
1321       to 0.5*2^-1074, with ternary value < 0 */
1322   char str[] = "2.47032822920623272089E-324";
1323   mpfr_t z;
1324   int inex;
1325 
1326   emin = mpfr_get_emin ();
1327   mpfr_init2 (z, 53);
1328   set_emin (-1073);
1329   /* with emin = -1073, the smallest positive number is 0.5*2^emin = 2^(-1074),
1330      thus str should be rounded to 2^(-1074) with inex > 0 */
1331   inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN);
1332   MPFR_ASSERTN(inex > 0 && mpfr_cmp_ui_2exp (z, 1, -1074) == 0);
1333   set_emin (-1074);
1334   /* with emin = -1074, str should be rounded to 2^(-1075) with inex < 0 */
1335   inex = mpfr_strtofr (z, str, NULL, 10, MPFR_RNDN);
1336   MPFR_ASSERTN(inex < 0 && mpfr_cmp_ui_2exp (z, 1, -1075) == 0);
1337   mpfr_clear (z);
1338   set_emin (emin);
1339 }
1340 
1341 /* r13299 fails with 8-bit limbs (micro-gmp/8). */
1342 static void
1343 bug20181127 (void)
1344 {
1345   char s[] = "9.Z6nrLVSMG1bDcCF2ONJdX@-183295525";  /* base 58 */
1346   mpfr_t x, y;
1347 
1348   mpfr_inits2 (6, x, y, (mpfr_ptr) 0);
1349   mpfr_set_ui_2exp (x, 5, -1073741701, MPFR_RNDN);
1350   mpfr_strtofr (y, s, NULL, 58, MPFR_RNDZ);
1351   if (! mpfr_equal_p (x, y))
1352     {
1353       printf ("Error in bug20181127 on %s (base 58)\n", s);
1354       printf ("Expected x = ");
1355       mpfr_dump (x);
1356       printf ("Got      y = ");
1357       mpfr_dump (y);
1358       printf ("*Note* In base 58, x ~= ");
1359       mpfr_out_str (stdout, 58, 8, x, MPFR_RNDN);
1360       printf ("\n");
1361       exit (1);
1362     }
1363   mpfr_clears (x, y, (mpfr_ptr) 0);
1364 }
1365 
1366 static void
1367 coverage (void)
1368 {
1369 #if _MPFR_EXP_FORMAT >= 3 && _MPFR_PREC_FORMAT == 3 && MPFR_PREC_BITS == 64
1370   char str3[] = "1@-2112009130072406892";
1371   char str31[] = "1@-511170973314085831";
1372   mpfr_t x;
1373   int inex;
1374   mpfr_exp_t emin;
1375 
1376   /* exercise assertion cy == 0 around line 698 of strtofr.c */
1377   emin = mpfr_get_emin ();
1378   set_emin (mpfr_get_emin_min ());
1379   /* emin = -4611686018427387903 on a 64-bit machine */
1380   mpfr_init2 (x, 1);
1381   inex = mpfr_strtofr (x, str3, NULL, 3, MPFR_RNDN);
1382   /* 3^-2112009130072406892 is slightly larger than (2^64)^-52303988630398057
1383      thus we should get inex < 0 */
1384   MPFR_ASSERTN(inex < 0);
1385   MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -52303988630398057 * 64) == 0);
1386   inex = mpfr_strtofr (x, str31, NULL, 31, MPFR_RNDN);
1387   /* 31^-511170973314085831 is slightly smaller than (2^64)^-39569396093273623
1388      thus we should get inex > 0 */
1389   MPFR_ASSERTN(inex > 0);
1390   MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -39569396093273623 * 64) == 0);
1391   mpfr_clear (x);
1392   set_emin (emin);
1393 #endif
1394 }
1395 
1396 #define BSIZE 512
1397 
1398 static void
1399 random_tests (void)
1400 {
1401   char s0[BSIZE], s1[BSIZE], s2[BSIZE+64];
1402   mpfr_t x0, x1, x2;
1403   int prec, i;
1404 
1405   for (prec = MPFR_PREC_MIN; prec < 300; prec++)
1406     {
1407       mpfr_inits2 (prec, x0, x1, x2, (mpfr_ptr) 0);
1408 
1409       for (i = 0; i < 20; i++)
1410         {
1411           const char *num_to_text;
1412           mpfr_exp_t e0, e1;
1413           int base, j, k, neg;
1414           int noteq = 0;
1415           char d;
1416 
1417           /* We want the same exponent for x0 and its successor x1.
1418              This is not possible for precision 1 in base 2. */
1419           do
1420             base = 2 + (randlimb () % 61);
1421           while (prec == 1 && base == 2);
1422 
1423           num_to_text = base <= 36 ? num_to_text36 : num_to_text62;
1424 
1425           do
1426             {
1427               /* Let's consider only positive numbers. We should test
1428                  negative numbers, but they should be built later, just
1429                  for the test itself. */
1430               tests_default_random (x0, 0,
1431                                     mpfr_get_emin (), mpfr_get_emax (), 1);
1432               mpfr_set (x1, x0, MPFR_RNDN);
1433               mpfr_nextabove (x1);
1434               mpfr_get_str (s0, &e0, base, BSIZE - 1, x0, MPFR_RNDU);
1435               mpfr_get_str (s1, &e1, base, BSIZE - 1, x1, MPFR_RNDD);
1436             }
1437           while (! (mpfr_regular_p (x0) && mpfr_regular_p (x1) && e0 == e1));
1438 
1439           /* 0 < x0 <= (s0,e) <= (s1,e) <= x1 with e = e0 = e1.
1440              Let's build a string s2 randomly formed by:
1441              - the common prefix of s0 and s1;
1442              - some of the following digits of s0 (possibly none);
1443              - the next digit of s0 + 1;
1444              - some of the following digits of s1 (possibly none).
1445              Then 0 < x0 <= (s0,e) < (s2,e) <= (s1,e) <= x1, and with
1446              a very high probability that (s2,e) < (s1,e); noteq is
1447              set to true in this case.
1448              For instance, if:
1449                s0 = 123456789
1450                s1 = 124012345
1451              one can have, e.g.:
1452                s2 = 12345734
1453                s2 = 123556789
1454                s2 = 124
1455                s2 = 124012
1456              s2 is not taken completely randomly between s0 and s1, but it
1457              will be built rather easily, and with the randomness of x0,
1458              we should cover all cases, with s2 very close to s0, s2 very
1459              close to s1, or not too close to either. */
1460 
1461           neg = RAND_BOOL ();
1462           s2[0] = neg ? '-' : '+';
1463           s2[1] = '.';
1464 
1465           for (j = 0;
1466                MPFR_ASSERTN (s0[j] != 0 && s1[j] != 0), s0[j] == s1[j];
1467                j++)
1468             s2[j+2] = s0[j];
1469 
1470           /* k is the position of the first differing digit. */
1471           k = j;
1472 
1473           while (j < BSIZE - 2 && randlimb () % 8 != 0)
1474             {
1475               MPFR_ASSERTN (s0[j] != 0);
1476               s2[j+2] = s0[j];
1477               j++;
1478             }
1479 
1480           MPFR_ASSERTN (s0[j] != 0);
1481           /* We will increment the next digit. Thus while s0[j] is the
1482              maximum digit, go back until this is no longer the case
1483              (the first digit after the common prefix cannot be the
1484              maximum digit, so that we will stop early enough). */
1485           while ((d = s0[j]) == num_to_text[base - 1])
1486             j--;
1487           noteq = j != k;
1488           s2[j+2] = d = *(strchr (num_to_text, d) + 1);
1489           if (d != s1[j])
1490             noteq = 1;
1491           j++;
1492 
1493           while (j < BSIZE - 1 && randlimb () % 8 != 0)
1494             {
1495               MPFR_ASSERTN (s1[j] != 0);
1496               s2[j+2] = s1[j];
1497               j++;
1498             }
1499 
1500           sprintf (s2 + (j+2), "@%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) e0);
1501 
1502           while (noteq == 0 && j < BSIZE - 1)
1503             {
1504               if (s1[j] != '0')
1505                 noteq = 1;
1506               j++;
1507             }
1508 
1509           if (neg)
1510             {
1511               mpfr_neg (x0, x0, MPFR_RNDN);
1512               mpfr_neg (x1, x1, MPFR_RNDN);
1513             }
1514 
1515           if (noteq)
1516             {
1517               mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDZ);
1518               if (! mpfr_equal_p (x2, x0))
1519                 {
1520                   printf ("Error in random_tests for prec=%d i=%d base=%d\n",
1521                           prec, i, base);
1522                   printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
1523                   printf ("x0 = ");
1524                   mpfr_dump (x0);
1525                   printf ("x2 = ");
1526                   mpfr_dump (x2);
1527                   exit (1);
1528                 }
1529             }
1530 
1531           mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDA);
1532           if (! mpfr_equal_p (x2, x1))
1533             {
1534               printf ("Error in random_tests for prec=%d i=%d base=%d\n",
1535                       prec, i, base);
1536               printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
1537               printf ("x1 = ");
1538               mpfr_dump (x1);
1539               printf ("x2 = ");
1540               mpfr_dump (x2);
1541               exit (1);
1542             }
1543         }
1544       mpfr_clears (x0, x1, x2, (mpfr_ptr) 0);
1545     }
1546 }
1547 
1548 int
1549 main (int argc, char *argv[])
1550 {
1551   tests_start_mpfr ();
1552 
1553   coverage ();
1554   check_special();
1555   check_reftable ();
1556   check_parse ();
1557   check_overflow ();
1558   check_retval ();
1559   bug20081028 ();
1560   test20100310 ();
1561   bug20120814 ();
1562   bug20120829 ();
1563   bug20161217 ();
1564   bug20170308 ();
1565   bug20181127 ();
1566   random_tests ();
1567 
1568   tests_end_mpfr ();
1569   return 0;
1570 }
1571