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
check_special(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
check_reftable(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
check_parse(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
check_overflow(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
check_retval(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
bug20081028(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
test20100310(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
bug20120814(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
bug20120829(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
bug20161217(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
bug20170308(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
bug20181127(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 /* Bug reported by Michael Jones (case i = 0 below)
1367 https://sympa.inria.fr/sympa/arc/mpfr/2023-06/msg00000.html
1368 This yields an integer overflow -LONG_MIN. The result might still
1369 be correct, but a runtime error is obtained with an UB sanitizer:
1370 strtofr.c:745:11: runtime error: negation of -9223372036854775808 [...]
1371 Details after an analysis:
1372 With GCC 4.9.4 and tcc, one gets an assertion failure:
1373 mpn_exp.c:94: MPFR assertion failed: e > 0
1374 And if all assertions are disabled with
1375 ./configure --enable-assert=none CC=gcc-4.9
1376 one gets an incorrect result:
1377 Error in bug20230606 for i = 0
1378 Expected x = 0
1379 Got x = 0.11001100110011001E-3
1380 This issue is not visible with GCC 8.4.0 and later, even with -O0,
1381 because GCC now transforms "-X >= 0" to "X <= 0" (which is valid
1382 under the ISO C rules). Note that such an optimization generally
1383 makes buggy code (which assumes "wrapping") fail; here, it makes
1384 the bug invisible!
1385
1386 Case i = 1 should be identical.
1387
1388 Case i = 2 shows another bug (probably with all compilers):
1389 Error in bug20230606 for i = 2
1390 Expected x = 0
1391 Got x = 0.11111111111111111E1073741823
1392 or with an UB sanitizer:
1393 strtofr.c:428:19: runtime error: signed integer overflow: [...]
1394 This is the bug mentioned at
1395 https://sympa.inria.fr/sympa/arc/mpfr/2023-06/msg00001.html
1396 */
1397 static void
bug20230606(void)1398 bug20230606 (void)
1399 {
1400 const char *const s[] = {
1401 "0.1E-99999999999999999999",
1402 ".1E-99999999999999999999",
1403 ".01E-99999999999999999999" };
1404 mpfr_t x;
1405 int i;
1406
1407 mpfr_init2 (x, 17);
1408 for (i = 0; i < numberof (s); i++)
1409 {
1410 mpfr_strtofr (x, s[i], NULL, 10, MPFR_RNDZ);
1411 if (!mpfr_zero_p (x) || mpfr_signbit (x) != 0)
1412 {
1413 printf ("Error in bug20230606 for i = %d\n", i);
1414 printf ("Expected x = 0\n");
1415 printf ("Got x = ");
1416 mpfr_dump (x);
1417 exit (1);
1418 }
1419 }
1420 mpfr_clear (x);
1421 }
1422
1423 static void
coverage(void)1424 coverage (void)
1425 {
1426 #if _MPFR_EXP_FORMAT >= 3 && _MPFR_PREC_FORMAT == 3 && MPFR_PREC_BITS == 64
1427 char str3[] = "1@-2112009130072406892";
1428 char str31[] = "1@-511170973314085831";
1429 mpfr_t x;
1430 int inex;
1431 mpfr_exp_t emin;
1432
1433 /* exercise assertion cy == 0 around line 698 of strtofr.c */
1434 emin = mpfr_get_emin ();
1435 set_emin (mpfr_get_emin_min ());
1436 /* emin = -4611686018427387903 on a 64-bit machine */
1437 mpfr_init2 (x, 1);
1438 inex = mpfr_strtofr (x, str3, NULL, 3, MPFR_RNDN);
1439 /* 3^-2112009130072406892 is slightly larger than (2^64)^-52303988630398057
1440 thus we should get inex < 0 */
1441 MPFR_ASSERTN(inex < 0);
1442 MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -52303988630398057 * 64) == 0);
1443 inex = mpfr_strtofr (x, str31, NULL, 31, MPFR_RNDN);
1444 /* 31^-511170973314085831 is slightly smaller than (2^64)^-39569396093273623
1445 thus we should get inex > 0 */
1446 MPFR_ASSERTN(inex > 0);
1447 MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, -39569396093273623 * 64) == 0);
1448 mpfr_clear (x);
1449 set_emin (emin);
1450 #endif
1451 }
1452
1453 #define BSIZE 512
1454
1455 static void
random_tests(void)1456 random_tests (void)
1457 {
1458 char s0[BSIZE], s1[BSIZE], s2[BSIZE+64];
1459 mpfr_t x0, x1, x2;
1460 int prec, i;
1461
1462 for (prec = MPFR_PREC_MIN; prec < 300; prec++)
1463 {
1464 mpfr_inits2 (prec, x0, x1, x2, (mpfr_ptr) 0);
1465
1466 for (i = 0; i < 20; i++)
1467 {
1468 const char *num_to_text;
1469 mpfr_exp_t e0, e1;
1470 int base, j, k, neg;
1471 int noteq = 0;
1472 char d;
1473
1474 /* We want the same exponent for x0 and its successor x1.
1475 This is not possible for precision 1 in base 2. */
1476 do
1477 base = 2 + (randlimb () % 61);
1478 while (prec == 1 && base == 2);
1479
1480 num_to_text = base <= 36 ? num_to_text36 : num_to_text62;
1481
1482 do
1483 {
1484 /* Let's consider only positive numbers. We should test
1485 negative numbers, but they should be built later, just
1486 for the test itself. */
1487 tests_default_random (x0, 0,
1488 mpfr_get_emin (), mpfr_get_emax (), 1);
1489 mpfr_set (x1, x0, MPFR_RNDN);
1490 mpfr_nextabove (x1);
1491 mpfr_get_str (s0, &e0, base, BSIZE - 1, x0, MPFR_RNDU);
1492 mpfr_get_str (s1, &e1, base, BSIZE - 1, x1, MPFR_RNDD);
1493 }
1494 while (! (mpfr_regular_p (x0) && mpfr_regular_p (x1) && e0 == e1));
1495
1496 /* 0 < x0 <= (s0,e) <= (s1,e) <= x1 with e = e0 = e1.
1497 Let's build a string s2 randomly formed by:
1498 - the common prefix of s0 and s1;
1499 - some of the following digits of s0 (possibly none);
1500 - the next digit of s0 + 1;
1501 - some of the following digits of s1 (possibly none).
1502 Then 0 < x0 <= (s0,e) < (s2,e) <= (s1,e) <= x1, and with
1503 a very high probability that (s2,e) < (s1,e); noteq is
1504 set to true in this case.
1505 For instance, if:
1506 s0 = 123456789
1507 s1 = 124012345
1508 one can have, e.g.:
1509 s2 = 12345734
1510 s2 = 123556789
1511 s2 = 124
1512 s2 = 124012
1513 s2 is not taken completely randomly between s0 and s1, but it
1514 will be built rather easily, and with the randomness of x0,
1515 we should cover all cases, with s2 very close to s0, s2 very
1516 close to s1, or not too close to either. */
1517
1518 neg = RAND_BOOL ();
1519 s2[0] = neg ? '-' : '+';
1520 s2[1] = '.';
1521
1522 for (j = 0;
1523 MPFR_ASSERTN (s0[j] != 0 && s1[j] != 0), s0[j] == s1[j];
1524 j++)
1525 s2[j+2] = s0[j];
1526
1527 /* k is the position of the first differing digit. */
1528 k = j;
1529
1530 while (j < BSIZE - 2 && randlimb () % 8 != 0)
1531 {
1532 MPFR_ASSERTN (s0[j] != 0);
1533 s2[j+2] = s0[j];
1534 j++;
1535 }
1536
1537 MPFR_ASSERTN (s0[j] != 0);
1538 /* We will increment the next digit. Thus while s0[j] is the
1539 maximum digit, go back until this is no longer the case
1540 (the first digit after the common prefix cannot be the
1541 maximum digit, so that we will stop early enough). */
1542 while ((d = s0[j]) == num_to_text[base - 1])
1543 j--;
1544 noteq = j != k;
1545 s2[j+2] = d = *(strchr (num_to_text, d) + 1);
1546 if (d != s1[j])
1547 noteq = 1;
1548 j++;
1549
1550 while (j < BSIZE - 1 && randlimb () % 8 != 0)
1551 {
1552 MPFR_ASSERTN (s1[j] != 0);
1553 s2[j+2] = s1[j];
1554 j++;
1555 }
1556
1557 sprintf (s2 + (j+2), "@%" MPFR_EXP_FSPEC "d", (mpfr_eexp_t) e0);
1558
1559 while (noteq == 0 && j < BSIZE - 1)
1560 {
1561 if (s1[j] != '0')
1562 noteq = 1;
1563 j++;
1564 }
1565
1566 if (neg)
1567 {
1568 mpfr_neg (x0, x0, MPFR_RNDN);
1569 mpfr_neg (x1, x1, MPFR_RNDN);
1570 }
1571
1572 if (noteq)
1573 {
1574 mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDZ);
1575 if (! mpfr_equal_p (x2, x0))
1576 {
1577 printf ("Error in random_tests for prec=%d i=%d base=%d\n",
1578 prec, i, base);
1579 printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
1580 printf ("x0 = ");
1581 mpfr_dump (x0);
1582 printf ("x2 = ");
1583 mpfr_dump (x2);
1584 exit (1);
1585 }
1586 }
1587
1588 mpfr_strtofr (x2, s2, NULL, base, MPFR_RNDA);
1589 if (! mpfr_equal_p (x2, x1))
1590 {
1591 printf ("Error in random_tests for prec=%d i=%d base=%d\n",
1592 prec, i, base);
1593 printf ("s0 = %s\ns1 = %s\ns2 = %s\n", s0, s1, s2);
1594 printf ("x1 = ");
1595 mpfr_dump (x1);
1596 printf ("x2 = ");
1597 mpfr_dump (x2);
1598 exit (1);
1599 }
1600 }
1601 mpfr_clears (x0, x1, x2, (mpfr_ptr) 0);
1602 }
1603 }
1604
1605 int
main(int argc,char * argv[])1606 main (int argc, char *argv[])
1607 {
1608 tests_start_mpfr ();
1609
1610 coverage ();
1611 check_special();
1612 check_reftable ();
1613 check_parse ();
1614 check_overflow ();
1615 check_retval ();
1616 bug20081028 ();
1617 test20100310 ();
1618 bug20120814 ();
1619 bug20120829 ();
1620 bug20161217 ();
1621 bug20170308 ();
1622 bug20181127 ();
1623 bug20230606 ();
1624 random_tests ();
1625
1626 tests_end_mpfr ();
1627 return 0;
1628 }
1629