tsprintf.c revision 1.1.1.4 1 /* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf,
2 and mpfr_vsnprintf
3
4 Copyright 2007-2018 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6
7 This file is part of the GNU MPFR Library.
8
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24 /* Include config.h before using ANY configure macros if needed. */
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
30 #include <stdarg.h>
31
32 #include <float.h>
33
34 #ifdef HAVE_LOCALE_H
35 #include <locale.h>
36 #endif
37
38 #include "mpfr-test.h"
39
40 const int prec_max_printf = 5000; /* limit for random precision in
41 random_double() */
42 #define BUF_SIZE 65536
43
44 const char pinf_str[] = "inf";
45 const char pinf_uc_str[] = "INF";
46 const char minf_str[] = "-inf";
47 const char minf_uc_str[] = "-INF";
48 const char nan_str[] = "nan";
49 const char nan_uc_str[] = "NAN";
50
51 int randsize;
52
53 /* 1. compare expected string with the string BUFFER returned by
54 mpfr_sprintf(buffer, fmt, x)
55 2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */
56 static int
57 check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x)
58 {
59 int n0, n1;
60 char buffer[BUF_SIZE];
61
62 /* test mpfr_sprintf */
63 n0 = mpfr_sprintf (buffer, fmt, x);
64 if (strcmp (buffer, expected) != 0)
65 {
66 printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt);
67 printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer);
68
69 exit (1);
70 }
71
72 /* test mpfr_snprintf */
73 randsize = (int) (randlimb () % (n0 + 3)) - 3; /* between -3 and n0 - 1 */
74 if (randsize < 0)
75 {
76 n1 = mpfr_snprintf (NULL, 0, fmt, x);
77 }
78 else
79 {
80 buffer[randsize] = 17;
81 n1 = mpfr_snprintf (buffer, randsize, fmt, x);
82 if (buffer[randsize] != 17)
83 {
84 printf ("Buffer overflow in mpfr_snprintf for randsize = %d!\n",
85 randsize);
86 exit (1);
87 }
88 }
89 if (n0 != n1)
90 {
91 printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n",
92 randsize, fmt);
93 printf ("expected: %d\ngot: %d\nx='", n0, n1);
94 mpfr_printf (fmt, x);
95 printf ("'\n");
96 exit (1);
97 }
98 if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0)
99 || (randsize == 1 && buffer[0] != '\0'))
100 {
101 char part_expected[BUF_SIZE];
102 strncpy (part_expected, expected, randsize);
103 part_expected[randsize - 1] = '\0';
104 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n",
105 randsize, fmt);
106 printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer);
107 exit (1);
108 }
109 return n0;
110 }
111
112 /* 1. compare expected string with the string BUFFER returned by
113 mpfr_vsprintf(buffer, fmt, ...)
114 2. then, test mpfr_vsnprintf. */
115 static int
116 check_vsprintf (const char *expected, const char *fmt, ...)
117 {
118 int n0, n1;
119 char buffer[BUF_SIZE];
120 va_list ap0, ap1;
121
122 va_start (ap0, fmt);
123 n0 = mpfr_vsprintf (buffer, fmt, ap0);
124 va_end (ap0);
125
126 if (strcmp (buffer, expected) != 0)
127 {
128 printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt);
129 printf ("expected: \"%s\"\ngot: \"%s\"\n", expected, buffer);
130 exit (1);
131 }
132
133 va_start (ap1, fmt);
134
135 /* test mpfr_snprintf */
136 randsize = (int) (randlimb () % (n0 + 3)) - 3; /* between -3 and n0 - 1 */
137 if (randsize < 0)
138 {
139 n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1);
140 }
141 else
142 {
143 buffer[randsize] = 17;
144 n1 = mpfr_vsnprintf (buffer, randsize, fmt, ap1);
145 if (buffer[randsize] != 17)
146 {
147 printf ("Buffer overflow in mpfr_vsnprintf for randsize = %d!\n",
148 randsize);
149 exit (1);
150 }
151 }
152
153 va_end (ap1);
154
155 if (n0 != n1)
156 {
157 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n",
158 randsize, fmt);
159 printf ("expected: %d\ngot: %d\n", n0, n1);
160 exit (1);
161 }
162 if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0)
163 || (randsize == 1 && buffer[0] != '\0'))
164 {
165 char part_expected[BUF_SIZE];
166
167 strncpy (part_expected, expected, randsize);
168 part_expected[randsize - 1] = '\0';
169 printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n",
170 randsize, fmt);
171 printf ("expected: \"%s\"\ngot: \"%s\"\n", part_expected, buffer);
172 exit (1);
173 }
174
175 return n0;
176 }
177
178 static void
179 native_types (void)
180 {
181 int c = 'a';
182 int i = -1;
183 unsigned int ui = 1;
184 double d = -1.25;
185 char s[] = "test";
186
187 char buf[255];
188
189 sprintf (buf, "%c", c);
190 check_vsprintf (buf, "%c", c);
191
192 sprintf (buf, "%d", i);
193 check_vsprintf (buf, "%d", i);
194
195 sprintf (buf, "%e", d);
196 check_vsprintf (buf, "%e", d);
197
198 sprintf (buf, "%f", d);
199 check_vsprintf (buf, "%f", d);
200
201 sprintf (buf, "%i", i);
202 check_vsprintf (buf, "%i", i);
203
204 sprintf (buf, "%g", d);
205 check_vsprintf (buf, "%g", d);
206
207 sprintf (buf, "%o", i);
208 check_vsprintf (buf, "%o", i);
209
210 sprintf (buf, "%s", s);
211 check_vsprintf (buf, "%s", s);
212
213 sprintf (buf, "--%s++", "");
214 check_vsprintf (buf, "--%s++", "");
215
216 sprintf (buf, "%u", ui);
217 check_vsprintf (buf, "%u", ui);
218
219 sprintf (buf, "%x", ui);
220 check_vsprintf (buf, "%x", ui);
221 }
222
223 static int
224 decimal (void)
225 {
226 mpfr_prec_t p = 128;
227 mpfr_t x;
228 mpfr_t z;
229 mpfr_init (z);
230 mpfr_init2 (x, p);
231
232 /* specifier 'P' for precision */
233 check_vsprintf ("128", "%Pu", p);
234 check_vsprintf ("00128", "%.5Pu", p);
235
236 /* special numbers */
237 mpfr_set_inf (x, 1);
238 check_sprintf (pinf_str, "%Re", x);
239 check_sprintf (pinf_str, "%RUe", x);
240 check_sprintf (pinf_uc_str, "%RE", x);
241 check_sprintf (pinf_uc_str, "%RDE", x);
242 check_sprintf (pinf_str, "%Rf", x);
243 check_sprintf (pinf_str, "%RYf", x);
244 check_sprintf (pinf_uc_str, "%RF", x);
245 check_sprintf (pinf_uc_str, "%RZF", x);
246 check_sprintf (pinf_str, "%Rg", x);
247 check_sprintf (pinf_str, "%RNg", x);
248 check_sprintf (pinf_uc_str, "%RG", x);
249 check_sprintf (pinf_uc_str, "%RUG", x);
250 check_sprintf (" inf", "%010Re", x);
251 check_sprintf (" inf", "%010RDe", x);
252
253 mpfr_set_inf (x, -1);
254 check_sprintf (minf_str, "%Re", x);
255 check_sprintf (minf_str, "%RYe", x);
256 check_sprintf (minf_uc_str, "%RE", x);
257 check_sprintf (minf_uc_str, "%RZE", x);
258 check_sprintf (minf_str, "%Rf", x);
259 check_sprintf (minf_str, "%RNf", x);
260 check_sprintf (minf_uc_str, "%RF", x);
261 check_sprintf (minf_uc_str, "%RUF", x);
262 check_sprintf (minf_str, "%Rg", x);
263 check_sprintf (minf_str, "%RDg", x);
264 check_sprintf (minf_uc_str, "%RG", x);
265 check_sprintf (minf_uc_str, "%RYG", x);
266 check_sprintf (" -inf", "%010Re", x);
267 check_sprintf (" -inf", "%010RZe", x);
268
269 mpfr_set_nan (x);
270 check_sprintf (nan_str, "%Re", x);
271 check_sprintf (nan_str, "%RNe", x);
272 check_sprintf (nan_uc_str, "%RE", x);
273 check_sprintf (nan_uc_str, "%RUE", x);
274 check_sprintf (nan_str, "%Rf", x);
275 check_sprintf (nan_str, "%RDf", x);
276 check_sprintf (nan_uc_str, "%RF", x);
277 check_sprintf (nan_uc_str, "%RYF", x);
278 check_sprintf (nan_str, "%Rg", x);
279 check_sprintf (nan_str, "%RZg", x);
280 check_sprintf (nan_uc_str, "%RG", x);
281 check_sprintf (nan_uc_str, "%RNG", x);
282 check_sprintf (" nan", "%010Re", x);
283
284 /* positive numbers */
285 mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
286 mpfr_set_ui (z, 0, MPFR_RNDD);
287
288 /* simplest case right justified */
289 check_sprintf (" 1.899347461279296875e+07", "%30Re", x);
290 check_sprintf (" 2e+07", "%30.0Re", x);
291 check_sprintf (" 18993474.612793", "%30Rf", x);
292 check_sprintf (" 18993474.6127930", "%30.7Rf", x);
293 check_sprintf (" 1.89935e+07", "%30Rg", x);
294 check_sprintf (" 2e+07", "%30.0Rg", x);
295 check_sprintf (" 18993474.61279296875", "%30.19Rg", x);
296 check_sprintf (" 0e+00", "%30.0Re", z);
297 check_sprintf (" 0", "%30.0Rf", z);
298 check_sprintf (" 0.0000", "%30.4Rf", z);
299 check_sprintf (" 0", "%30.0Rg", z);
300 check_sprintf (" 0", "%30.4Rg", z);
301 /* sign or space, pad with leading zeros */
302 check_sprintf (" 000001.899347461279296875E+07", "% 030RE", x);
303 check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x);
304 check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x);
305 check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z);
306 check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z);
307 /* sign + or -, left justified */
308 check_sprintf ("+1.899347461279296875e+07 ", "%+-30Re", x);
309 check_sprintf ("+2e+07 ", "%+-30.0Re", x);
310 check_sprintf ("+0e+00 ", "%+-30.0Re", z);
311 check_sprintf ("+0 ", "%+-30.0Rf", z);
312 /* decimal point, left justified, precision and rounding parameter */
313 check_vsprintf ("1.9E+07 ", "%#-10.*R*E", 1, MPFR_RNDN, x);
314 check_vsprintf ("2.E+07 ", "%#*.*R*E", -10, 0, MPFR_RNDN, x);
315 check_vsprintf ("2.E+07 ", "%#-10.*R*G", 0, MPFR_RNDN, x);
316 check_vsprintf ("0.E+00 ", "%#-10.*R*E", 0, MPFR_RNDN, z);
317 check_vsprintf ("0. ", "%#-10.*R*F", 0, MPFR_RNDN, z);
318 check_vsprintf ("0. ", "%#-10.*R*G", 0, MPFR_RNDN, z);
319 /* sign or space */
320 check_sprintf (" 1.899e+07", "% .3RNe", x);
321 check_sprintf (" 2e+07", "% .0RNe", x);
322 /* sign + or -, decimal point, pad with leading zeros */
323 check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x);
324 check_sprintf ("+00001.E+07", "%0+#11.0RZE", x);
325 check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z);
326 check_sprintf ("+00000000.0", "%0+#11.1RZF", z);
327 /* pad with leading zero */
328 check_sprintf ("0000001.899347461279296875e+07", "%030RDe", x);
329 check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x);
330 /* sign or space, decimal point, left justified */
331 check_sprintf (" 1.8E+07 ", "%- #11.1RDE", x);
332 check_sprintf (" 1.E+07 ", "%- #11.0RDE", x);
333 /* large requested precision */
334 check_sprintf ("18993474.61279296875", "%.2147483647Rg", x);
335
336 /* negative numbers */
337 mpfr_mul_si (x, x, -1, MPFR_RNDD);
338 mpfr_mul_si (z, z, -1, MPFR_RNDD);
339
340 /* sign + or - */
341 check_sprintf (" -1.8e+07", "%+10.1RUe", x);
342 check_sprintf (" -1e+07", "%+10.0RUe", x);
343 check_sprintf (" -0e+00", "%+10.0RUe", z);
344 check_sprintf (" -0", "%+10.0RUf", z);
345
346
347 /* neighborhood of 1 */
348 mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN);
349 check_sprintf ("9.9993896484375E-01 ", "%-20RE", x);
350 check_sprintf ("9.9993896484375E-01 ", "%-20.RE", x);
351 check_sprintf ("1E+00 ", "%-20.0RE", x);
352 check_sprintf ("1.0E+00 ", "%-20.1RE", x);
353 check_sprintf ("1.00E+00 ", "%-20.2RE", x);
354 check_sprintf ("9.999E-01 ", "%-20.3RE", x);
355 check_sprintf ("9.9994E-01 ", "%-20.4RE", x);
356 check_sprintf ("0.999939 ", "%-20RF", x);
357 check_sprintf ("0.999939 ", "%-20.RF", x);
358 check_sprintf ("1 ", "%-20.0RF", x);
359 check_sprintf ("1.0 ", "%-20.1RF", x);
360 check_sprintf ("1.00 ", "%-20.2RF", x);
361 check_sprintf ("1.000 ", "%-20.3RF", x);
362 check_sprintf ("0.9999 ", "%-20.4RF", x);
363 check_sprintf ("0.999939 ", "%-#20RF", x);
364 check_sprintf ("0.999939 ", "%-#20.RF", x);
365 check_sprintf ("1. ", "%-#20.0RF", x);
366 check_sprintf ("1.0 ", "%-#20.1RF", x);
367 check_sprintf ("1.00 ", "%-#20.2RF", x);
368 check_sprintf ("1.000 ", "%-#20.3RF", x);
369 check_sprintf ("0.9999 ", "%-#20.4RF", x);
370 check_sprintf ("1 ", "%-20.0RG", x);
371 check_sprintf ("1 ", "%-20.1RG", x);
372 check_sprintf ("1 ", "%-20.2RG", x);
373 check_sprintf ("1 ", "%-20.3RG", x);
374 check_sprintf ("0.9999 ", "%-20.4RG", x);
375 check_sprintf ("0.999939 ", "%-#20RG", x);
376 check_sprintf ("0.999939 ", "%-#20.RG", x);
377 check_sprintf ("1. ", "%-#20.0RG", x);
378 check_sprintf ("1. ", "%-#20.1RG", x);
379 check_sprintf ("1.0 ", "%-#20.2RG", x);
380 check_sprintf ("1.00 ", "%-#20.3RG", x);
381 check_sprintf ("0.9999 ", "%-#20.4RG", x);
382
383 /* multiple of 10 */
384 mpfr_set_str (x, "1e17", 10, MPFR_RNDN);
385 check_sprintf ("1e+17", "%Re", x);
386 check_sprintf ("1.000e+17", "%.3Re", x);
387 check_sprintf ("100000000000000000", "%.0Rf", x);
388 check_sprintf ("100000000000000000.0", "%.1Rf", x);
389 check_sprintf ("100000000000000000.000000", "%'Rf", x);
390 check_sprintf ("100000000000000000.0", "%'.1Rf", x);
391
392 mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */
393 check_sprintf ("1e-17", "%Re", x);
394 check_sprintf ("0.000000", "%Rf", x);
395 check_sprintf ("1e-17", "%Rg", x);
396 check_sprintf ("0.0", "%.1RDf", x);
397 check_sprintf ("0.0", "%.1RZf", x);
398 check_sprintf ("0.1", "%.1RUf", x);
399 check_sprintf ("0.1", "%.1RYf", x);
400 check_sprintf ("0", "%.0RDf", x);
401 check_sprintf ("0", "%.0RZf", x);
402 check_sprintf ("1", "%.0RUf", x);
403 check_sprintf ("1", "%.0RYf", x);
404
405 /* multiple of 10 with 'g' style */
406 mpfr_set_str (x, "10", 10, MPFR_RNDN);
407 check_sprintf ("10", "%Rg", x);
408 check_sprintf ("1e+01", "%.0Rg", x);
409 check_sprintf ("1e+01", "%.1Rg", x);
410 check_sprintf ("10", "%.2Rg", x);
411
412 mpfr_ui_div (x, 1, x, MPFR_RNDN);
413 check_sprintf ("0.1", "%Rg", x);
414 check_sprintf ("0.1", "%.0Rg", x);
415 check_sprintf ("0.1", "%.1Rg", x);
416
417 mpfr_set_str (x, "1000", 10, MPFR_RNDN);
418 check_sprintf ("1000", "%Rg", x);
419 check_sprintf ("1e+03", "%.0Rg", x);
420 check_sprintf ("1e+03", "%.3Rg", x);
421 check_sprintf ("1000", "%.4Rg", x);
422
423 mpfr_ui_div (x, 1, x, MPFR_RNDN);
424 check_sprintf ("0.001", "%Rg", x);
425 check_sprintf ("0.001", "%.0Rg", x);
426 check_sprintf ("0.001", "%.1Rg", x);
427
428 mpfr_set_str (x, "100000", 10, MPFR_RNDN);
429 check_sprintf ("100000", "%Rg", x);
430 check_sprintf ("1e+05", "%.0Rg", x);
431 check_sprintf ("1e+05", "%.5Rg", x);
432 check_sprintf ("100000", "%.6Rg", x);
433
434 mpfr_ui_div (x, 1, x, MPFR_RNDN);
435 check_sprintf ("1e-05", "%Rg", x);
436 check_sprintf ("1e-05", "%.0Rg", x);
437 check_sprintf ("1e-05", "%.1Rg", x);
438
439 /* check rounding mode */
440 mpfr_set_str (x, "0.0076", 10, MPFR_RNDN);
441 check_sprintf ("0.007", "%.3RDF", x);
442 check_sprintf ("0.007", "%.3RZF", x);
443 check_sprintf ("0.008", "%.3RF", x);
444 check_sprintf ("0.008", "%.3RUF", x);
445 check_sprintf ("0.008", "%.3RYF", x);
446 check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x);
447
448 /* check limit between %f-style and %g-style */
449 mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN);
450 check_sprintf ("0.0001", "%.0Rg", x);
451 check_sprintf ("9e-05", "%.0RDg", x);
452 check_sprintf ("0.0001", "%.1Rg", x);
453 check_sprintf ("0.0001", "%.2Rg", x);
454 check_sprintf ("9.99e-05", "%.3Rg", x);
455
456 /* trailing zeros */
457 mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */
458 check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
459 check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x);
460 check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x);
461 check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x);
462
463 /* bug 20081023 */
464 check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
465 mpfr_set_str (x, "1.9999", 10, MPFR_RNDN);
466 check_sprintf ("1.999900 ", "%-#10.7RG", x);
467 check_sprintf ("1.9999 ", "%-10.7RG", x);
468 mpfr_set_ui (x, 1, MPFR_RNDN);
469 check_sprintf ("1.", "%#.1Rg", x);
470 check_sprintf ("1. ", "%-#5.1Rg", x);
471 check_sprintf (" 1.0", "%#5.2Rg", x);
472 check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x);
473 check_sprintf ("1", "%.30Rg", x);
474 mpfr_set_ui (x, 0, MPFR_RNDN);
475 check_sprintf ("0.", "%#.1Rg", x);
476 check_sprintf ("0. ", "%-#5.1Rg", x);
477 check_sprintf (" 0.0", "%#5.2Rg", x);
478 check_sprintf ("0.00000000000000000000000000000", "%#.30Rg", x);
479 check_sprintf ("0", "%.30Rg", x);
480
481 /* following tests with precision 53 bits */
482 mpfr_set_prec (x, 53);
483
484 /* Exponent zero has a plus sign */
485 mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10,
486 MPFR_RNDN);
487 check_sprintf ("-1.0e+00", "%- #0.1Re", x);
488
489 /* Decimal point and no figure after it with '#' flag and 'G' style */
490 mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN);
491 check_sprintf ("-1.", "%- #0.1RG", x);
492
493 /* precision zero */
494 mpfr_set_d (x, 9.5, MPFR_RNDN);
495 check_sprintf ("9", "%.0RDf", x);
496 check_sprintf ("10", "%.0RUf", x);
497
498 mpfr_set_d (x, 19.5, MPFR_RNDN);
499 check_sprintf ("19", "%.0RDf", x);
500 check_sprintf ("20", "%.0RUf", x);
501
502 mpfr_set_d (x, 99.5, MPFR_RNDN);
503 check_sprintf ("99", "%.0RDf", x);
504 check_sprintf ("100", "%.0RUf", x);
505
506 mpfr_set_d (x, -9.5, MPFR_RNDN);
507 check_sprintf ("-10", "%.0RDf", x);
508 check_sprintf ("-10", "%.0RYf", x);
509 check_sprintf ("-10", "%.0Rf", x);
510 check_sprintf ("-1e+01", "%.0Re", x);
511 check_sprintf ("-1e+01", "%.0Rg", x);
512 mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN);
513 check_sprintf ("0", "%.0Rf", x);
514 check_sprintf ("5e-01", "%.0Re", x);
515 check_sprintf ("0.5", "%.0Rg", x);
516 mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN);
517 check_sprintf ("2", "%.0Rf", x);
518 mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
519 check_sprintf ("2", "%.0Rf", x);
520 mpfr_set_ui (x, 0x1f, MPFR_RNDN);
521 check_sprintf ("0x1p+5", "%.0Ra", x);
522 mpfr_set_ui (x, 3, MPFR_RNDN);
523 check_sprintf ("1p+2", "%.0Rb", x);
524
525 /* round to next ten power with %f but not with %g */
526 mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN);
527 check_sprintf ("-0.1", "%.1Rf", x);
528 check_sprintf ("-0.0", "%.1RZf", x);
529 check_sprintf ("-0.07", "%.1Rg", x);
530 check_sprintf ("-0.06", "%.1RZg", x);
531
532 /* round to next ten power and do not remove trailing zeros */
533 mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN);
534 check_sprintf ("0.1", "%#.1Rg", x);
535 check_sprintf ("0.10", "%#.2Rg", x);
536 check_sprintf ("0.099", "%#.2RZg", x);
537
538 /* Halfway cases */
539 mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
540 check_sprintf ("2e+00", "%.0Re", x);
541 mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
542 check_sprintf ("2e+00", "%.0Re", x);
543 mpfr_set_str (x, "9.5", 10, MPFR_RNDN);
544 check_sprintf ("1e+01", "%.0Re", x);
545 mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
546 check_sprintf ("1.2e+00", "%.1Re", x);
547 mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
548 check_sprintf ("1.8e+00", "%.1Re", x);
549 mpfr_set_str (x, "-0.5", 10, MPFR_RNDN);
550 check_sprintf ("-0", "%.0Rf", x);
551 mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
552 check_sprintf ("1.2", "%.1Rf", x);
553 mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
554 check_sprintf ("1.8", "%.1Rf", x);
555 mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
556 check_sprintf ("2", "%.1Rg", x);
557 mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
558 check_sprintf ("2", "%.1Rg", x);
559 mpfr_set_str (x, "9.25", 10, MPFR_RNDN);
560 check_sprintf ("9.2", "%.2Rg", x);
561 mpfr_set_str (x, "9.75", 10, MPFR_RNDN);
562 check_sprintf ("9.8", "%.2Rg", x);
563
564 /* assertion failure in r6320 */
565 mpfr_set_str (x, "-9.996", 10, MPFR_RNDN);
566 check_sprintf ("-10.0", "%.1Rf", x);
567
568 /* regression in MPFR 3.1.0 (bug introduced in r7761, fixed in r7931) */
569 check_sprintf ("-10", "%.2Rg", x);
570
571 mpfr_clears (x, z, (mpfr_ptr) 0);
572 return 0;
573 }
574
575 static int
576 hexadecimal (void)
577 {
578 mpfr_t x, z;
579 mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
580
581 /* special */
582 mpfr_set_inf (x, 1);
583 check_sprintf (pinf_str, "%Ra", x);
584 check_sprintf (pinf_str, "%RUa", x);
585 check_sprintf (pinf_str, "%RDa", x);
586 check_sprintf (pinf_uc_str, "%RA", x);
587 check_sprintf (pinf_uc_str, "%RYA", x);
588 check_sprintf (pinf_uc_str, "%RZA", x);
589 check_sprintf (pinf_uc_str, "%RNA", x);
590
591 mpfr_set_inf (x, -1);
592 check_sprintf (minf_str, "%Ra", x);
593 check_sprintf (minf_str, "%RYa", x);
594 check_sprintf (minf_str, "%RZa", x);
595 check_sprintf (minf_str, "%RNa", x);
596 check_sprintf (minf_uc_str, "%RA", x);
597 check_sprintf (minf_uc_str, "%RUA", x);
598 check_sprintf (minf_uc_str, "%RDA", x);
599
600 mpfr_set_nan (x);
601 check_sprintf (nan_str, "%Ra", x);
602 check_sprintf (nan_uc_str, "%RA", x);
603
604 /* regular numbers */
605 mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN);
606 mpfr_set_ui (z, 0, MPFR_RNDZ);
607
608 /* simplest case right justified */
609 check_sprintf (" 0xf.edcba987654321p+24", "%25Ra", x);
610 check_sprintf (" 0xf.edcba987654321p+24", "%25RUa", x);
611 check_sprintf (" 0xf.edcba987654321p+24", "%25RDa", x);
612 check_sprintf (" 0xf.edcba987654321p+24", "%25RYa", x);
613 check_sprintf (" 0xf.edcba987654321p+24", "%25RZa", x);
614 check_sprintf (" 0xf.edcba987654321p+24", "%25RNa", x);
615 check_sprintf (" 0x1p+28", "%25.0Ra", x);
616 check_sprintf (" 0x0p+0", "%25.0Ra", z);
617 /* sign or space, pad with leading zeros */
618 check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x);
619 check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x);
620 check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z);
621 /* sign + or -, left justified */
622 check_sprintf ("+0xf.edcba987654321p+24 ", "%+-25Ra", x);
623 check_sprintf ("+0x1p+28 ", "%+-25.0Ra", x);
624 check_sprintf ("+0x0p+0 ", "%+-25.0Ra", z);
625 /* decimal point, left justified, precision and rounding parameter */
626 check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x);
627 check_vsprintf ("0X1.P+28 ", "%#-10.*R*A", 0, MPFR_RNDN, x);
628 check_vsprintf ("0X0.P+0 ", "%#-10.*R*A", 0, MPFR_RNDN, z);
629 /* sign or space */
630 check_sprintf (" 0xf.eddp+24", "% .3RNa", x);
631 check_sprintf (" 0x1p+28", "% .0RNa", x);
632 /* sign + or -, decimal point, pad with leading zeros */
633 check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x);
634 check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x);
635 check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z);
636 /* pad with leading zero */
637 check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x);
638 check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x);
639 /* sign or space, decimal point, left justified */
640 check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x);
641 check_sprintf (" 0XF.P+24 " , "%- #11.0RDA", x);
642
643 mpfr_mul_si (x, x, -1, MPFR_RNDD);
644 mpfr_mul_si (z, z, -1, MPFR_RNDD);
645
646 /* sign + or - */
647 check_sprintf ("-0xf.ep+24", "%+10.1RUa", x);
648 check_sprintf (" -0xfp+24", "%+10.0RUa", x);
649 check_sprintf (" -0x0p+0", "%+10.0RUa", z);
650
651 /* rounding bit is zero */
652 mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN);
653 check_sprintf ("0XFP+0", "%.0RNA", x);
654 /* tie case in round to nearest mode */
655 mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN);
656 check_sprintf ("0x9.p-1", "%#.0RNa", x);
657 mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN);
658 check_sprintf ("-0xap-1", "%.0RNa", x);
659 /* trailing zeros in fractional part */
660 check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x);
661 /* rounding bit is one and the first non zero bit is far away */
662 mpfr_set_prec (x, 1024);
663 mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN);
664 mpfr_nextabove (x);
665 check_sprintf ("0XFP+0", "%.0RNA", x);
666
667 /* with more than one limb */
668 mpfr_set_prec (x, 300);
669 mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff"
670 "fffffffffffffffff", 16, MPFR_RNDN);
671 check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x);
672 check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x);
673 check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x);
674 check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x);
675 check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x);
676 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
677 "%.40RNa", x);
678 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
679 "%.40RZa", x);
680 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
681 "%.40RYa", x);
682 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
683 "%.40RDa", x);
684 check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
685 "%.40RUa", x);
686
687 mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff"
688 "ffffffffffffffffff", 16, MPFR_RNDN);
689 check_sprintf ("0XFP+0", "%.0RNA", x);
690 check_sprintf ("0XFP+0", "%.0RZA", x);
691 check_sprintf ("0X1P+4", "%.0RYA", x);
692 check_sprintf ("0XFP+0", "%.0RDA", x);
693 check_sprintf ("0X1P+4", "%.0RUA", x);
694 check_sprintf ("0XF.8P+0", "%.1RNA", x);
695 check_sprintf ("0XF.7P+0", "%.1RZA", x);
696 check_sprintf ("0XF.8P+0", "%.1RYA", x);
697 check_sprintf ("0XF.7P+0", "%.1RDA", x);
698 check_sprintf ("0XF.8P+0", "%.1RUA", x);
699
700 /* do not round up to the next power of the base */
701 mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff"
702 "ffffffffffffffffff", 16, MPFR_RNDN);
703 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
704 "%.40RNa", x);
705 check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
706 "%.40RZa", x);
707 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
708 "%.40RYa", x);
709 check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
710 "%.40RDa", x);
711 check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
712 "%.40RUa", x);
713
714 mpfr_clears (x, z, (mpfr_ptr) 0);
715 return 0;
716 }
717
718 static int
719 binary (void)
720 {
721 mpfr_t x;
722 mpfr_t z;
723 mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
724
725 /* special */
726 mpfr_set_inf (x, 1);
727 check_sprintf (pinf_str, "%Rb", x);
728
729 mpfr_set_inf (x, -1);
730 check_sprintf (minf_str, "%Rb", x);
731
732 mpfr_set_nan (x);
733 check_sprintf (nan_str, "%Rb", x);
734
735 /* regular numbers */
736 mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN);
737 mpfr_set_ui (z, 0, MPFR_RNDN);
738
739 /* simplest case: right justified */
740 check_sprintf (" 1.1100101011001101p+9", "%25Rb", x);
741 check_sprintf (" 0p+0", "%25Rb", z);
742 /* sign or space, pad with leading zeros */
743 check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x);
744 check_sprintf (" 000000000000000000000p+0", "% 025Rb", z);
745 /* sign + or -, left justified */
746 check_sprintf ("+1.1100101011001101p+9 ", "%+-25Rb", x);
747 check_sprintf ("+0p+0 ", "%+-25Rb", z);
748 /* sign or space */
749 check_sprintf (" 1.110p+9", "% .3RNb", x);
750 check_sprintf (" 1.1101p+9", "% .4RNb", x);
751 check_sprintf (" 0.0000p+0", "% .4RNb", z);
752 /* sign + or -, decimal point, pad with leading zeros */
753 check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x);
754 check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x);
755 check_sprintf ("+000000.p+0", "%0+#11.0RNb", z);
756 /* pad with leading zero */
757 check_sprintf ("00001.1100101011001101p+9", "%025RDb", x);
758 /* sign or space, decimal point (unused), left justified */
759 check_sprintf (" 1.1p+9 ", "%- #11.1RDb", x);
760 check_sprintf (" 1.p+9 ", "%- #11.0RDb", x);
761 check_sprintf (" 1.p+10 ", "%- #11.0RUb", x);
762 check_sprintf (" 1.p+9 ", "%- #11.0RZb", x);
763 check_sprintf (" 1.p+10 ", "%- #11.0RYb", x);
764 check_sprintf (" 1.p+10 ", "%- #11.0RNb", x);
765
766 mpfr_mul_si (x, x, -1, MPFR_RNDD);
767 mpfr_mul_si (z, z, -1, MPFR_RNDD);
768
769 /* sign + or - */
770 check_sprintf (" -1.1p+9", "%+10.1RUb", x);
771 check_sprintf (" -0.0p+0", "%+10.1RUb", z);
772
773 /* precision 0 */
774 check_sprintf ("-1p+10", "%.0RNb", x);
775 check_sprintf ("-1p+10", "%.0RDb", x);
776 check_sprintf ("-1p+9", "%.0RUb", x);
777 check_sprintf ("-1p+9", "%.0RZb", x);
778 check_sprintf ("-1p+10", "%.0RYb", x);
779 /* round to next base power */
780 check_sprintf ("-1.0p+10", "%.1RNb", x);
781 check_sprintf ("-1.0p+10", "%.1RDb", x);
782 check_sprintf ("-1.0p+10", "%.1RYb", x);
783 /* do not round to next base power */
784 check_sprintf ("-1.1p+9", "%.1RUb", x);
785 check_sprintf ("-1.1p+9", "%.1RZb", x);
786 /* rounding bit is zero */
787 check_sprintf ("-1.11p+9", "%.2RNb", x);
788 /* tie case in round to nearest mode */
789 check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x);
790 /* trailing zeros in fractional part */
791 check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x);
792
793 mpfr_clears (x, z, (mpfr_ptr) 0);
794 return 0;
795 }
796
797 static int
798 mixed (void)
799 {
800 int n1;
801 int n2;
802 int i = 121;
803 #ifdef PRINTF_L
804 long double d = 1. / 31.;
805 #endif
806 mpf_t mpf;
807 mpq_t mpq;
808 mpz_t mpz;
809 mpfr_t x;
810 mpfr_rnd_t rnd;
811 int k;
812
813 mpf_init (mpf);
814 mpf_set_ui (mpf, 40);
815 mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */
816 mpq_init (mpq);
817 mpq_set_ui (mpq, 123456, 4567890);
818 mpz_init (mpz);
819 mpz_fib_ui (mpz, 64);
820 mpfr_init (x);
821 mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN);
822 rnd = MPFR_RNDD;
823
824 check_vsprintf ("121%", "%i%%", i);
825 check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x);
826 check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x);
827 check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd,
828 x);
829 check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i);
830 check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq);
831
832 /* TODO: Systematically test with and without %n in check_vsprintf? */
833 /* Do the test several times due to random parameters in check_vsprintf
834 and the use of %n. In r11501, n2 is incorrect (seems random) when
835 randsize <= 0, i.e. when the size argument of mpfr_vsnprintf is 0. */
836 for (k = 0; k < 30; k++)
837 {
838 n2 = -17;
839 /* If this value is obtained for n2 after the check_vsprintf call below,
840 this probably means that n2 has not been written as expected. */
841 n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323",
842 "%i, %.*Rf, %Ff%n", i, 12, x, mpf, &n2);
843 if (n1 != n2)
844 {
845 printf ("error in number of characters written by mpfr_vsprintf"
846 " for k = %d, randsize = %d\n", k, randsize);
847 printf ("expected: %d\n", n2);
848 printf (" got: %d\n", n1);
849 exit (1);
850 }
851 }
852
853 #ifdef PRINTF_L
854 /* under MinGW, -D__USE_MINGW_ANSI_STDIO is required to support %Lf
855 see https://gcc.gnu.org/ml/gcc/2013-03/msg00103.html */
856 check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258",
857 "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
858 #endif
859
860 mpf_clear (mpf);
861 mpq_clear (mpq);
862 mpz_clear (mpz);
863 mpfr_clear (x);
864 return 0;
865 }
866
867 #if MPFR_LCONV_DPTS
868
869 /* Check with locale "da_DK". On most platforms, decimal point is ','
870 and thousands separator is '.'; the test is not performed if this
871 is not the case or if the locale doesn't exist. */
872 static int
873 locale_da_DK (void)
874 {
875 mpfr_prec_t p = 128;
876 mpfr_t x;
877
878 if (setlocale (LC_ALL, "da_DK") == 0 ||
879 localeconv()->decimal_point[0] != ',' ||
880 localeconv()->thousands_sep[0] != '.')
881 return 0;
882
883 mpfr_init2 (x, p);
884
885 /* positive numbers */
886 mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
887
888 /* simplest case right justified with thousands separator */
889 check_sprintf (" 1,899347461279296875e+07", "%'30Re", x);
890 check_sprintf (" 1,89935e+07", "%'30Rg", x);
891 check_sprintf (" 18.993.474,61279296875", "%'30.19Rg", x);
892 check_sprintf (" 18.993.474,612793", "%'30Rf", x);
893
894 /* sign or space, pad, thousands separator with leading zeros */
895 check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x);
896 check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x);
897 check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x);
898 check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x);
899
900 #define T1 "000"
901 #define T2 ".000"
902 #define S1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1
903 #define S2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 ","
904
905 mpfr_set_ui (x, 48, MPFR_RNDN);
906 mpfr_exp10 (x, x, MPFR_RNDN);
907 check_sprintf ("1" S1, "%.0Rf", x);
908 check_sprintf ("1" S2, "%'#.0Rf", x);
909 check_sprintf ("1" S2 "0000", "%'.4Rf", x);
910 mpfr_mul_ui (x, x, 10, MPFR_RNDN);
911 check_sprintf ("10" S1, "%.0Rf", x);
912 check_sprintf ("10" S2, "%'#.0Rf", x);
913 check_sprintf ("10" S2 "0000", "%'.4Rf", x);
914 mpfr_mul_ui (x, x, 10, MPFR_RNDN);
915 check_sprintf ("100" S1, "%.0Rf", x);
916 check_sprintf ("100" S2, "%'#.0Rf", x);
917 check_sprintf ("100" S2 "0000", "%'.4Rf", x);
918
919 mpfr_clear (x);
920 return 0;
921 }
922
923 #endif /* MPFR_LCONV_DPTS */
924
925 /* check concordance between mpfr_asprintf result with a regular mpfr float
926 and with a regular double float */
927 static int
928 random_double (void)
929 {
930 mpfr_t x; /* random regular mpfr float */
931 double y; /* regular double float (equal to x) */
932
933 char flag[] =
934 {
935 '-',
936 '+',
937 ' ',
938 '#',
939 '0', /* no ambiguity: first zeros are flag zero */
940 '\'' /* SUS extension */
941 };
942 /* no 'a': mpfr and glibc do not have the same semantic */
943 char specifier[] =
944 {
945 'e',
946 'f',
947 'g',
948 'E',
949 'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for
950 regular numbers */
951 'G',
952 };
953 int spec; /* random index in specifier[] */
954 int prec; /* random value for precision field */
955
956 /* in the format string for mpfr_t variable, the maximum length is
957 reached by something like "%-+ #0'.*Rf", that is 12 characters. */
958 #define FMT_MPFR_SIZE 12
959 char fmt_mpfr[FMT_MPFR_SIZE];
960 char *ptr_mpfr;
961
962 /* in the format string for double variable, the maximum length is
963 reached by something like "%-+ #0'.*f", that is 11 characters. */
964 #define FMT_SIZE 11
965 char fmt[FMT_SIZE];
966 char *ptr;
967
968 int xi;
969 char *xs;
970 int yi;
971 char *ys;
972
973 int i, j, jmax;
974
975 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
976
977 for (i = 0; i < 1000; ++i)
978 {
979 /* 1. random double */
980 do
981 {
982 y = DBL_RAND ();
983 }
984 #ifdef HAVE_DENORMS
985 while (0);
986 #else
987 while (ABS(y) < DBL_MIN);
988 #endif
989
990 if (randlimb () % 2 == 0)
991 y = -y;
992
993 mpfr_set_d (x, y, MPFR_RNDN);
994 if (y != mpfr_get_d (x, MPFR_RNDN))
995 /* conversion error: skip this one */
996 continue;
997
998 /* 2. build random format strings fmt_mpfr and fmt */
999 ptr_mpfr = fmt_mpfr;
1000 ptr = fmt;
1001 *ptr_mpfr++ = *ptr++ = '%';
1002 /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */
1003 spec = (int) (randlimb() % 6);
1004 /* random flags, but no ' flag with %e or with non-glibc */
1005 #if __MPFR_GLIBC(1,0)
1006 jmax = (spec == 0 || spec == 3) ? 5 : 6;
1007 #else
1008 jmax = 5;
1009 #endif
1010 for (j = 0; j < jmax; j++)
1011 {
1012 if (randlimb() % 3 == 0)
1013 *ptr_mpfr++ = *ptr++ = flag[j];
1014 }
1015 *ptr_mpfr++ = *ptr++ = '.';
1016 *ptr_mpfr++ = *ptr++ = '*';
1017 *ptr_mpfr++ = 'R';
1018 *ptr_mpfr++ = *ptr++ = specifier[spec];
1019 *ptr_mpfr = *ptr = '\0';
1020 MPFR_ASSERTN (ptr - fmt < FMT_SIZE);
1021 MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE);
1022
1023 /* advantage small precision */
1024 if (randlimb() % 2 == 0)
1025 prec = (int) (randlimb() % 10);
1026 else
1027 prec = (int) (randlimb() % prec_max_printf);
1028
1029 /* 3. calls and checks */
1030 /* the double float case is handled by the libc asprintf through
1031 gmp_asprintf */
1032 xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x);
1033 yi = mpfr_asprintf (&ys, fmt, prec, y);
1034
1035 /* test if XS and YS differ, beware that ISO C99 doesn't specify
1036 the sign of a zero exponent (the C99 rationale says: "The sign
1037 of a zero exponent in %e format is unspecified. The committee
1038 knows of different implementations and choose not to require
1039 implementations to document their behavior in this case
1040 (by making this be implementation defined behaviour). Most
1041 implementations use a "+" sign, e.g., 1.2e+00; but there is at
1042 least one implementation that uses the sign of the unlimited
1043 precision result, e.g., the 0.987 would be 9.87e-01, so could
1044 end up as 1e-00 after rounding to one digit of precision."),
1045 while mpfr always uses '+' */
1046 if (xi != yi
1047 || ((strcmp (xs, ys) != 0)
1048 && (spec == 1 || spec == 4
1049 || ((strstr (xs, "e+00") == NULL
1050 || strstr (ys, "e-00") == NULL)
1051 && (strstr (xs, "E+00") == NULL
1052 || strstr (ys, "E-00") == NULL)))))
1053 {
1054 mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n",
1055 fmt_mpfr, prec, x);
1056 printf ("expected: %s\n", ys);
1057 printf (" got: %s\n", xs);
1058 printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec);
1059
1060 exit (1);
1061 }
1062
1063 mpfr_free_str (xs);
1064 mpfr_free_str (ys);
1065 }
1066
1067 mpfr_clear (x);
1068 return 0;
1069 }
1070
1071 static void
1072 bug20080610 (void)
1073 {
1074 /* bug on icc found on June 10, 2008 */
1075 /* this is not a bug but a different implementation choice: ISO C99 doesn't
1076 specify the sign of a zero exponent (see note in random_double above). */
1077 mpfr_t x;
1078 double y;
1079 int xi;
1080 char *xs;
1081 int yi;
1082 char *ys;
1083
1084 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
1085
1086 y = -9.95645044213728791504536275169812142849e-01;
1087 mpfr_set_d (x, y, MPFR_RNDN);
1088
1089 xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x);
1090 yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y);
1091
1092 if (xi != yi || strcmp (xs, ys) != 0)
1093 {
1094 printf ("Error in bug20080610\n");
1095 printf ("expected: %s\n", ys);
1096 printf (" got: %s\n", xs);
1097 printf ("xi=%d yi=%d\n", xi, yi);
1098
1099 exit (1);
1100 }
1101
1102 mpfr_free_str (xs);
1103 mpfr_free_str (ys);
1104 mpfr_clear (x);
1105 }
1106
1107 static void
1108 bug20081214 (void)
1109 {
1110 /* problem with glibc 2.3.6, December 14, 2008:
1111 the system asprintf outputs "-1.0" instead of "-1.". */
1112 mpfr_t x;
1113 double y;
1114 int xi;
1115 char *xs;
1116 int yi;
1117 char *ys;
1118
1119 mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
1120
1121 y = -9.90597761233942053494e-01;
1122 mpfr_set_d (x, y, MPFR_RNDN);
1123
1124 xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x);
1125 yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y);
1126
1127 if (xi != yi || strcmp (xs, ys) != 0)
1128 {
1129 mpfr_printf ("Error in bug20081214\n"
1130 "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x);
1131 printf ("expected: %s\n", ys);
1132 printf (" got: %s\n", xs);
1133 printf ("xi=%d yi=%d\n", xi, yi);
1134
1135 exit (1);
1136 }
1137
1138 mpfr_free_str (xs);
1139 mpfr_free_str (ys);
1140 mpfr_clear (x);
1141 }
1142
1143 static void
1144 bug20111102 (void)
1145 {
1146 mpfr_t t;
1147 char s[100];
1148
1149 mpfr_init2 (t, 84);
1150 mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN);
1151 mpfr_sprintf (s, "%.20RNg", t);
1152 if (strcmp (s, "1000") != 0)
1153 {
1154 printf ("Error in bug20111102, expected 1000, got %s\n", s);
1155 exit (1);
1156 }
1157 mpfr_clear (t);
1158 }
1159
1160 /* In particular, the following test makes sure that the rounding
1161 * for %Ra and %Rb is not done on the MPFR number itself (as it
1162 * would overflow). Note: it has been reported on comp.std.c that
1163 * some C libraries behave differently on %a, but this is a bug.
1164 */
1165 static void
1166 check_emax_aux (mpfr_exp_t e)
1167 {
1168 mpfr_t x;
1169 char *s1, s2[256];
1170 int i;
1171 mpfr_exp_t emax;
1172
1173 MPFR_ASSERTN (e <= LONG_MAX);
1174 emax = mpfr_get_emax ();
1175 set_emax (e);
1176
1177 mpfr_init2 (x, 16);
1178
1179 mpfr_set_inf (x, 1);
1180 mpfr_nextbelow (x);
1181
1182 i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x);
1183 MPFR_ASSERTN (i > 0);
1184
1185 mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3);
1186
1187 if (strcmp (s1, s2) != 0)
1188 {
1189 printf ("Error in check_emax_aux for emax = ");
1190 if (e > LONG_MAX)
1191 printf ("(>LONG_MAX)\n");
1192 else
1193 printf ("%ld\n", (long) e);
1194 printf ("Expected '%s'\n", s2);
1195 printf ("Got '%s'\n", s1);
1196 exit (1);
1197 }
1198
1199 mpfr_free_str (s1);
1200
1201 i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x);
1202 MPFR_ASSERTN (i > 0);
1203
1204 mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e);
1205
1206 if (strcmp (s1, s2) != 0)
1207 {
1208 printf ("Error in check_emax_aux for emax = ");
1209 if (e > LONG_MAX)
1210 printf ("(>LONG_MAX)\n");
1211 else
1212 printf ("%ld\n", (long) e);
1213 printf ("Expected %s\n", s2);
1214 printf ("Got %s\n", s1);
1215 exit (1);
1216 }
1217
1218 mpfr_free_str (s1);
1219
1220 mpfr_clear (x);
1221 set_emax (emax);
1222 }
1223
1224 static void
1225 check_emax (void)
1226 {
1227 check_emax_aux (15);
1228 check_emax_aux (MPFR_EMAX_MAX);
1229 }
1230
1231 static void
1232 check_emin_aux (mpfr_exp_t e)
1233 {
1234 mpfr_t x;
1235 char *s1, s2[256];
1236 int i;
1237 mpfr_exp_t emin;
1238 mpz_t ee;
1239
1240 MPFR_ASSERTN (e >= LONG_MIN);
1241 emin = mpfr_get_emin ();
1242 set_emin (e);
1243
1244 mpfr_init2 (x, 16);
1245 mpz_init (ee);
1246
1247 mpfr_setmin (x, e);
1248 mpz_set_si (ee, e);
1249 mpz_sub_ui (ee, ee, 1);
1250
1251 i = mpfr_asprintf (&s1, "%Ra", x);
1252 MPFR_ASSERTN (i > 0);
1253
1254 gmp_snprintf (s2, 256, "0x1p%Zd", ee);
1255
1256 if (strcmp (s1, s2) != 0)
1257 {
1258 printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
1259 printf ("Expected %s\n", s2);
1260 printf ("Got %s\n", s1);
1261 exit (1);
1262 }
1263
1264 mpfr_free_str (s1);
1265
1266 i = mpfr_asprintf (&s1, "%Rb", x);
1267 MPFR_ASSERTN (i > 0);
1268
1269 gmp_snprintf (s2, 256, "1p%Zd", ee);
1270
1271 if (strcmp (s1, s2) != 0)
1272 {
1273 printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
1274 printf ("Expected %s\n", s2);
1275 printf ("Got %s\n", s1);
1276 exit (1);
1277 }
1278
1279 mpfr_free_str (s1);
1280
1281 mpfr_clear (x);
1282 mpz_clear (ee);
1283 set_emin (emin);
1284 }
1285
1286 static void
1287 check_emin (void)
1288 {
1289 check_emin_aux (-15);
1290 check_emin_aux (mpfr_get_emin ());
1291 check_emin_aux (MPFR_EMIN_MIN);
1292 }
1293
1294 static void
1295 test20161214 (void)
1296 {
1297 mpfr_t x;
1298 char buf[32];
1299 const char s[] = "0x0.fffffffffffff8p+1024";
1300 int r;
1301
1302 mpfr_init2 (x, 64);
1303 mpfr_set_str (x, s, 16, MPFR_RNDN);
1304 r = mpfr_snprintf (buf, 32, "%.*RDf", -2, x);
1305 MPFR_ASSERTN(r == 316);
1306 r = mpfr_snprintf (buf, 32, "%.*RDf", INT_MIN + 1, x);
1307 MPFR_ASSERTN(r == 316);
1308 r = mpfr_snprintf (buf, 32, "%.*RDf", INT_MIN, x);
1309 MPFR_ASSERTN(r == 316);
1310 mpfr_clear (x);
1311 }
1312
1313 /* http://gforge.inria.fr/tracker/index.php?func=detail&aid=21056 */
1314 static void
1315 bug21056 (void)
1316 {
1317 mpfr_t x;
1318 const char s[] = "0x0.fffffffffffff8p+1024";
1319 int ndigits, r;
1320
1321 mpfr_init2 (x, 64);
1322
1323 mpfr_set_str (x, s, 16, MPFR_RNDN);
1324
1325 ndigits = 1000;
1326 r = mpfr_snprintf (0, 0, "%.*RDf", ndigits, x);
1327 /* the return value should be ndigits + 310 */
1328 MPFR_ASSERTN(r == ndigits + 310);
1329
1330 ndigits = INT_MAX - 310;
1331 r = mpfr_snprintf (0, 0, "%.*RDf", ndigits, x);
1332 MPFR_ASSERTN(r == INT_MAX);
1333
1334 ndigits = INT_MAX - 10;
1335 r = mpfr_snprintf (0, 0, "%.*RDa", ndigits, x);
1336 MPFR_ASSERTN(r == INT_MAX);
1337
1338 ndigits = INT_MAX - 7;
1339 r = mpfr_snprintf (0, 0, "%.*RDe", ndigits, x);
1340 MPFR_ASSERTN(r == INT_MAX);
1341
1342 ndigits = 1000;
1343 r = mpfr_snprintf (0, 0, "%.*RDg", ndigits, x);
1344 /* since trailing zeros are removed with %g, we get less digits */
1345 MPFR_ASSERTN(r == 309);
1346
1347 ndigits = INT_MAX;
1348 r = mpfr_snprintf (0, 0, "%.*RDg", ndigits, x);
1349 /* since trailing zeros are removed with %g, we get less digits */
1350 MPFR_ASSERTN(r == 309);
1351
1352 ndigits = INT_MAX - 1;
1353 r = mpfr_snprintf (0, 0, "%#.*RDg", ndigits, x);
1354 MPFR_ASSERTN(r == ndigits + 1);
1355
1356 mpfr_clear (x);
1357 }
1358
1359 /* Fails for i = 5, i.e. t[i] = (size_t) UINT_MAX + 1,
1360 with r11427 on 64-bit machines (4-byte int, 8-byte size_t).
1361 On such machines, t[5] converted to int typically gives 0.
1362 Note: the assumed behavior corresponds to the snprintf behavior
1363 in ISO C, but this conflicts with POSIX:
1364 https://sourceware.org/bugzilla/show_bug.cgi?id=14771#c2
1365 http://austingroupbugs.net/view.php?id=761
1366 */
1367 static void
1368 snprintf_size (void)
1369 {
1370 mpfr_t x;
1371 char buf[12];
1372 const char s[] = "17.00000000";
1373 size_t t[] = { 11, 12, 64, INT_MAX, (size_t) INT_MAX + 1,
1374 (size_t) UINT_MAX + 1, (size_t) UINT_MAX + 2,
1375 (size_t) -1 };
1376 int i, r;
1377
1378 mpfr_init2 (x, 64);
1379 mpfr_set_ui (x, 17, MPFR_RNDN);
1380
1381 for (i = 0; i < sizeof (t) / sizeof (*t); i++)
1382 {
1383 memset (buf, 0, sizeof (buf));
1384 /* r = snprintf (buf, t[i], "%.8f", 17.0); */
1385 r = mpfr_snprintf (buf, t[i], "%.8Rf", x);
1386 if (r != 11 || (t[i] > 11 && strcmp (buf, s) != 0))
1387 {
1388 printf ("Error in snprintf_size for i = %d:\n", i);
1389 printf ("expected r = 11, \"%s\"\n", s);
1390 printf ("got r = %d, \"%s\"\n", r, buf);
1391 exit (1);
1392 }
1393 }
1394
1395 mpfr_clear (x);
1396 }
1397
1398 /* With r11516, n2 gets a random value for i = 0 only!
1399 valgrind detects a problem for "nchar = buf.curr - buf.start;"
1400 in the spec.spec == 'n' case. Indeed, there is no buffer when
1401 size is 0. */
1402 static void
1403 percent_n (void)
1404 {
1405 int err = 0, i, j;
1406
1407 for (i = 0; i < 24; i++)
1408 for (j = 0; j < 3; j++)
1409 {
1410 volatile int n1, n2;
1411 char buffer[64];
1412
1413 memset (buffer, 0, 64);
1414 n2 = -17;
1415 n1 = mpfr_snprintf (buffer, i % 8, "%d%n", 123, &n2);
1416 if (n1 != 3 || n2 != 3)
1417 {
1418 printf ("Error 1 in percent_n: i = %d, n1 = %d, n2 = %d\n",
1419 i, n1, n2);
1420 err = 1;
1421 }
1422 }
1423
1424 if (err)
1425 exit (1);
1426 }
1427
1428 int
1429 main (int argc, char **argv)
1430 {
1431 int k;
1432
1433 tests_start_mpfr ();
1434
1435 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
1436 /* currently, we just check with 'C' locale */
1437 setlocale (LC_ALL, "C");
1438 #endif
1439
1440 bug20111102 ();
1441
1442 for (k = 0; k < 40; k++)
1443 {
1444 native_types ();
1445 hexadecimal ();
1446 binary ();
1447 decimal ();
1448
1449 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
1450 #if MPFR_LCONV_DPTS
1451 locale_da_DK ();
1452 /* Avoid a warning by doing the setlocale outside of this #if */
1453 #endif
1454 setlocale (LC_ALL, "C");
1455 #endif
1456 }
1457
1458 check_emax ();
1459 check_emin ();
1460 test20161214 ();
1461 bug21056 ();
1462 snprintf_size ();
1463 percent_n ();
1464 mixed ();
1465
1466 if (getenv ("MPFR_CHECK_LIBC_PRINTF"))
1467 {
1468 /* check against libc */
1469 random_double ();
1470 bug20081214 ();
1471 bug20080610 ();
1472 }
1473
1474 tests_end_mpfr ();
1475 return 0;
1476 }
1477
1478 #else /* HAVE_STDARG */
1479
1480 int
1481 main (void)
1482 {
1483 /* We have nothing to test. */
1484 return 77;
1485 }
1486
1487 #endif /* HAVE_STDARG */
1488