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