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