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