1/* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf,
2   and mpfr_vsnprintf
3
4Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
5Contributed by the AriC and Caramel projects, INRIA.
6
7This file is part of the GNU MPFR Library.
8
9The GNU MPFR Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 3 of the License, or (at your
12option) any later version.
13
14The GNU MPFR Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
21http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2251 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
38const int prec_max_printf = 5000; /* limit for random precision in
39                                     random_double() */
40#define BUF_SIZE 65536
41
42const char pinf_str[] = "inf";
43const char pinf_uc_str[] = "INF";
44const char minf_str[] = "-inf";
45const char minf_uc_str[] = "-INF";
46const char nan_str[] = "nan";
47const 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. */
52static int
53check_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. */
107static int
108check_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
170static void
171native_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
215static int
216decimal (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.00000000000000000000000000000", "%#.30Rg", x);
460  check_sprintf ("1", "%.30Rg", x);
461  mpfr_set_ui (x, 0, MPFR_RNDN);
462  check_sprintf ("0.000000000000000000000000000000", "%#.30Rg", x);
463  check_sprintf ("0", "%.30Rg", x);
464
465  /* following tests with precision 53 bits */
466  mpfr_set_prec (x, 53);
467
468  /* Exponent zero has a plus sign */
469  mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10,
470                MPFR_RNDN);
471  check_sprintf ("-1.0e+00", "%- #0.1Re", x);
472
473  /* Decimal point and no figure after it with '#' flag and 'G' style */
474  mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN);
475  check_sprintf ("-1.", "%- #0.1RG", x);
476
477  /* precision zero */
478  mpfr_set_d (x, 9.5, MPFR_RNDN);
479  check_sprintf ("9",    "%.0RDf", x);
480  check_sprintf ("10",    "%.0RUf", x);
481
482  mpfr_set_d (x, 19.5, MPFR_RNDN);
483  check_sprintf ("19",    "%.0RDf", x);
484  check_sprintf ("20",    "%.0RUf", x);
485
486  mpfr_set_d (x, 99.5, MPFR_RNDN);
487  check_sprintf ("99",    "%.0RDf", x);
488  check_sprintf ("100",   "%.0RUf", x);
489
490  mpfr_set_d (x, -9.5, MPFR_RNDN);
491  check_sprintf ("-10",    "%.0RDf", x);
492  check_sprintf ("-10",    "%.0RYf", x);
493  check_sprintf ("-10",    "%.0Rf", x);
494  check_sprintf ("-1e+01", "%.0Re", x);
495  check_sprintf ("-1e+01", "%.0Rg", x);
496  mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN);
497  check_sprintf ("0",      "%.0Rf", x);
498  check_sprintf ("5e-01",  "%.0Re", x);
499  check_sprintf ("0.5",    "%.0Rg", x);
500  mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN);
501  check_sprintf ("2",      "%.0Rf", x);
502  mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
503  check_sprintf ("2",      "%.0Rf", x);
504  mpfr_set_ui (x, 0x1f, MPFR_RNDN);
505  check_sprintf ("0x1p+5", "%.0Ra", x);
506  mpfr_set_ui (x, 3, MPFR_RNDN);
507  check_sprintf ("1p+2",   "%.0Rb", x);
508
509  /* round to next ten power with %f but not with %g */
510  mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN);
511  check_sprintf ("-0.1",  "%.1Rf", x);
512  check_sprintf ("-0.0",  "%.1RZf", x);
513  check_sprintf ("-0.07", "%.1Rg", x);
514  check_sprintf ("-0.06", "%.1RZg", x);
515
516  /* round to next ten power and do not remove trailing zeros */
517  mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN);
518  check_sprintf ("0.1",   "%#.1Rg", x);
519  check_sprintf ("0.10",  "%#.2Rg", x);
520  check_sprintf ("0.099", "%#.2RZg", x);
521
522  /* Halfway cases */
523  mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
524  check_sprintf ("2e+00", "%.0Re", x);
525  mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
526  check_sprintf ("2e+00", "%.0Re", x);
527  mpfr_set_str (x, "9.5", 10, MPFR_RNDN);
528  check_sprintf ("1e+01", "%.0Re", x);
529  mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
530  check_sprintf ("1.2e+00", "%.1Re", x);
531  mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
532  check_sprintf ("1.8e+00", "%.1Re", x);
533  mpfr_set_str (x, "-0.5", 10, MPFR_RNDN);
534  check_sprintf ("-0", "%.0Rf", x);
535  mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
536  check_sprintf ("1.2", "%.1Rf", x);
537  mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
538  check_sprintf ("1.8", "%.1Rf", x);
539  mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
540  check_sprintf ("2", "%.1Rg", x);
541  mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
542  check_sprintf ("2", "%.1Rg", x);
543  mpfr_set_str (x, "9.25", 10, MPFR_RNDN);
544  check_sprintf ("9.2", "%.2Rg", x);
545  mpfr_set_str (x, "9.75", 10, MPFR_RNDN);
546  check_sprintf ("9.8", "%.2Rg", x);
547
548  /* assertion failure in r6320 */
549  mpfr_set_str (x, "-9.996", 10, MPFR_RNDN);
550  check_sprintf ("-10.0", "%.1Rf", x);
551
552  mpfr_clears (x, z, (mpfr_ptr) 0);
553  return 0;
554}
555
556static int
557hexadecimal (void)
558{
559  mpfr_t x, z;
560  mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
561
562  /* special */
563  mpfr_set_inf (x, 1);
564  check_sprintf (pinf_str, "%Ra", x);
565  check_sprintf (pinf_str, "%RUa", x);
566  check_sprintf (pinf_str, "%RDa", x);
567  check_sprintf (pinf_uc_str, "%RA", x);
568  check_sprintf (pinf_uc_str, "%RYA", x);
569  check_sprintf (pinf_uc_str, "%RZA", x);
570  check_sprintf (pinf_uc_str, "%RNA", x);
571
572  mpfr_set_inf (x, -1);
573  check_sprintf (minf_str, "%Ra", x);
574  check_sprintf (minf_str, "%RYa", x);
575  check_sprintf (minf_str, "%RZa", x);
576  check_sprintf (minf_str, "%RNa", x);
577  check_sprintf (minf_uc_str, "%RA", x);
578  check_sprintf (minf_uc_str, "%RUA", x);
579  check_sprintf (minf_uc_str, "%RDA", x);
580
581  mpfr_set_nan (x);
582  check_sprintf (nan_str, "%Ra", x);
583  check_sprintf (nan_uc_str, "%RA", x);
584
585  /* regular numbers */
586  mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN);
587  mpfr_set_ui (z, 0, MPFR_RNDZ);
588
589  /* simplest case right justified */
590  check_sprintf ("   0xf.edcba987654321p+24", "%25Ra", x);
591  check_sprintf ("   0xf.edcba987654321p+24", "%25RUa", x);
592  check_sprintf ("   0xf.edcba987654321p+24", "%25RDa", x);
593  check_sprintf ("   0xf.edcba987654321p+24", "%25RYa", x);
594  check_sprintf ("   0xf.edcba987654321p+24", "%25RZa", x);
595  check_sprintf ("   0xf.edcba987654321p+24", "%25RNa", x);
596  check_sprintf ("                  0x1p+28", "%25.0Ra", x);
597  check_sprintf ("                   0x0p+0", "%25.0Ra", z);
598  /* sign or space, pad with leading zeros */
599  check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x);
600  check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x);
601  check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z);
602  /* sign + or -, left justified */
603  check_sprintf ("+0xf.edcba987654321p+24  ", "%+-25Ra", x);
604  check_sprintf ("+0x1p+28                 ", "%+-25.0Ra", x);
605  check_sprintf ("+0x0p+0                  ", "%+-25.0Ra", z);
606  /* decimal point, left justified, precision and rounding parameter */
607  check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x);
608  check_vsprintf ("0X1.P+28  ", "%#-10.*R*A", 0, MPFR_RNDN, x);
609  check_vsprintf ("0X0.P+0   ", "%#-10.*R*A", 0, MPFR_RNDN, z);
610  /* sign or space */
611  check_sprintf (" 0xf.eddp+24", "% .3RNa", x);
612  check_sprintf (" 0x1p+28",     "% .0RNa", x);
613  /* sign + or -, decimal point, pad with leading zeros */
614  check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x);
615  check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x);
616  check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z);
617  /* pad with leading zero */
618  check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x);
619  check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x);
620  /* sign or space, decimal point, left justified */
621  check_sprintf (" 0XF.EP+24 " , "%- #11.1RDA", x);
622  check_sprintf (" 0XF.P+24  " , "%- #11.0RDA", x);
623
624  mpfr_mul_si (x, x, -1, MPFR_RNDD);
625  mpfr_mul_si (z, z, -1, MPFR_RNDD);
626
627  /* sign + or - */
628  check_sprintf ("-0xf.ep+24", "%+10.1RUa", x);
629  check_sprintf ("  -0xfp+24", "%+10.0RUa", x);
630  check_sprintf ("   -0x0p+0", "%+10.0RUa", z);
631
632  /* rounding bit is zero */
633  mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN);
634  check_sprintf ("0XFP+0", "%.0RNA", x);
635  /* tie case in round to nearest mode */
636  mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN);
637  check_sprintf ("0x9.p-1", "%#.0RNa", x);
638  mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN);
639  check_sprintf ("-0xap-1", "%.0RNa", x);
640  /* trailing zeros in fractional part */
641  check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x);
642  /* rounding bit is one and the first non zero bit is far away */
643  mpfr_set_prec (x, 1024);
644  mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN);
645  mpfr_nextabove (x);
646  check_sprintf ("0XFP+0", "%.0RNA", x);
647
648  /* with more than one limb */
649  mpfr_set_prec (x, 300);
650  mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff"
651                "fffffffffffffffff", 16, MPFR_RNDN);
652  check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x);
653  check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x);
654  check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x);
655  check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x);
656  check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x);
657  check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
658                 "%.40RNa", x);
659  check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
660                 "%.40RZa", x);
661  check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
662                 "%.40RYa", x);
663  check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
664                 "%.40RDa", x);
665  check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
666                 "%.40RUa", x);
667
668  mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff"
669                "ffffffffffffffffff", 16, MPFR_RNDN);
670  check_sprintf ("0XFP+0", "%.0RNA", x);
671  check_sprintf ("0XFP+0", "%.0RZA", x);
672  check_sprintf ("0X1P+4", "%.0RYA", x);
673  check_sprintf ("0XFP+0", "%.0RDA", x);
674  check_sprintf ("0X1P+4", "%.0RUA", x);
675  check_sprintf ("0XF.8P+0", "%.1RNA", x);
676  check_sprintf ("0XF.7P+0", "%.1RZA", x);
677  check_sprintf ("0XF.8P+0", "%.1RYA", x);
678  check_sprintf ("0XF.7P+0", "%.1RDA", x);
679  check_sprintf ("0XF.8P+0", "%.1RUA", x);
680
681  /* do not round up to the next power of the base */
682  mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff"
683                "ffffffffffffffffff", 16, MPFR_RNDN);
684  check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
685                 "%.40RNa", x);
686  check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
687                 "%.40RZa", x);
688  check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
689                 "%.40RYa", x);
690  check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
691                 "%.40RDa", x);
692  check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
693                 "%.40RUa", x);
694
695  mpfr_clears (x, z, (mpfr_ptr) 0);
696  return 0;
697}
698
699static int
700binary (void)
701{
702  mpfr_t x;
703  mpfr_t z;
704  mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
705
706  /* special */
707  mpfr_set_inf (x, 1);
708  check_sprintf (pinf_str, "%Rb", x);
709
710  mpfr_set_inf (x, -1);
711  check_sprintf (minf_str, "%Rb", x);
712
713  mpfr_set_nan (x);
714  check_sprintf (nan_str, "%Rb", x);
715
716  /* regular numbers */
717  mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN);
718  mpfr_set_ui (z, 0, MPFR_RNDN);
719
720  /* simplest case: right justified */
721  check_sprintf ("    1.1100101011001101p+9", "%25Rb", x);
722  check_sprintf ("                     0p+0", "%25Rb", z);
723  /* sign or space, pad with leading zeros */
724  check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x);
725  check_sprintf (" 000000000000000000000p+0", "% 025Rb", z);
726  /* sign + or -, left justified */
727  check_sprintf ("+1.1100101011001101p+9   ", "%+-25Rb", x);
728  check_sprintf ("+0p+0                    ", "%+-25Rb", z);
729  /* sign or space */
730  check_sprintf (" 1.110p+9",  "% .3RNb", x);
731  check_sprintf (" 1.1101p+9", "% .4RNb", x);
732  check_sprintf (" 0.0000p+0", "% .4RNb", z);
733  /* sign + or -, decimal point, pad with leading zeros */
734  check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x);
735  check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x);
736  check_sprintf ("+000000.p+0", "%0+#11.0RNb", z);
737  /* pad with leading zero */
738  check_sprintf ("00001.1100101011001101p+9", "%025RDb", x);
739  /* sign or space, decimal point (unused), left justified */
740  check_sprintf (" 1.1p+9    ", "%- #11.1RDb", x);
741  check_sprintf (" 1.p+9     ", "%- #11.0RDb", x);
742  check_sprintf (" 1.p+10    ", "%- #11.0RUb", x);
743  check_sprintf (" 1.p+9     ", "%- #11.0RZb", x);
744  check_sprintf (" 1.p+10    ", "%- #11.0RYb", x);
745  check_sprintf (" 1.p+10    ", "%- #11.0RNb", x);
746
747  mpfr_mul_si (x, x, -1, MPFR_RNDD);
748  mpfr_mul_si (z, z, -1, MPFR_RNDD);
749
750  /* sign + or - */
751  check_sprintf ("   -1.1p+9", "%+10.1RUb", x);
752  check_sprintf ("   -0.0p+0", "%+10.1RUb", z);
753
754  /* precision 0 */
755  check_sprintf ("-1p+10", "%.0RNb", x);
756  check_sprintf ("-1p+10", "%.0RDb", x);
757  check_sprintf ("-1p+9",  "%.0RUb", x);
758  check_sprintf ("-1p+9",  "%.0RZb", x);
759  check_sprintf ("-1p+10", "%.0RYb", x);
760  /* round to next base power */
761  check_sprintf ("-1.0p+10", "%.1RNb", x);
762  check_sprintf ("-1.0p+10", "%.1RDb", x);
763  check_sprintf ("-1.0p+10", "%.1RYb", x);
764  /* do not round to next base power */
765  check_sprintf ("-1.1p+9", "%.1RUb", x);
766  check_sprintf ("-1.1p+9", "%.1RZb", x);
767  /* rounding bit is zero */
768  check_sprintf ("-1.11p+9", "%.2RNb", x);
769  /* tie case in round to nearest mode */
770  check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x);
771  /* trailing zeros in fractional part */
772  check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x);
773
774  mpfr_clears (x, z, (mpfr_ptr) 0);
775  return 0;
776}
777
778static int
779mixed (void)
780{
781  int n1;
782  int n2;
783  int i = 121;
784#ifndef NPRINTF_L
785  long double d = 1. / 31.;
786#endif
787  mpf_t mpf;
788  mpq_t mpq;
789  mpz_t mpz;
790  mpfr_t x;
791  mpfr_rnd_t rnd;
792
793  mpf_init (mpf);
794  mpf_set_ui (mpf, 40);
795  mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */
796  mpq_init (mpq);
797  mpq_set_ui (mpq, 123456, 4567890);
798  mpz_init (mpz);
799  mpz_fib_ui (mpz, 64);
800  mpfr_init (x);
801  mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN);
802  rnd = MPFR_RNDD;
803
804  check_vsprintf ("121%", "%i%%", i);
805  check_vsprintf ("121% -1.2345678875E+07", "%i%% %RNE", i, x);
806  check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x);
807  check_vsprintf ("10610209857723, -1.2345678875e+07", "%Zi, %R*e", mpz, rnd,
808                  x);
809  check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i);
810  check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq);
811  n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323", "%i, %.*Rf, %Ff%n",
812                       i, 12, x, mpf, &n2);
813  if (n1 != n2)
814    {
815      printf ("error in number of characters written by mpfr_vsprintf\n");
816      printf ("expected: %d\n", n2);
817      printf ("     got: %d\n", n1);
818      exit (1);
819    }
820
821#ifndef NPRINTF_L
822  check_vsprintf ("00000010610209857723, -1.2345678875e+07, 0.032258",
823                  "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
824#endif
825
826  mpf_clear (mpf);
827  mpq_clear (mpq);
828  mpz_clear (mpz);
829  mpfr_clear (x);
830  return 0;
831}
832
833/* Check with locale "da_DK". On most platforms, decimal point is ','
834   and thousands separator is '.'; the test is not performed if this
835   is not the case or if the locale doesn't exist. */
836static int
837locale_da_DK (void)
838{
839  mpfr_prec_t p = 128;
840  mpfr_t x;
841
842  if (setlocale (LC_ALL, "da_DK") == 0 ||
843      localeconv()->decimal_point[0] != ',' ||
844      localeconv()->thousands_sep[0] != '.')
845    return 0;
846
847  mpfr_init2 (x, p);
848
849  /* positive numbers */
850  mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
851
852  /* simplest case right justified with thousands separator */
853  check_sprintf ("      1,899347461279296875e+07", "%'30Re", x);
854  check_sprintf ("                   1,89935e+07", "%'30Rg", x);
855  check_sprintf ("        18.993.474,61279296875", "%'30.19Rg", x);
856  check_sprintf ("             18.993.474,612793", "%'30Rf", x);
857
858  /* sign or space, pad, thousands separator with leading zeros */
859  check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", x);
860  check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x);
861  check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x);
862  check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x);
863
864  mpfr_set_ui (x, 50, MPFR_RNDN);
865  mpfr_exp10 (x, x, MPFR_RNDN);
866  check_sprintf ("100000000000000000000000000000000000000000000000000", "%.0Rf",
867                 x);
868  check_sprintf
869    ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,",
870     "%'#.0Rf", x);
871  check_sprintf
872    ("100.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000,0000",
873     "%'.4Rf", x);
874
875  mpfr_clear (x);
876  return 0;
877}
878
879/* check concordance between mpfr_asprintf result with a regular mpfr float
880   and with a regular double float */
881static int
882random_double (void)
883{
884  mpfr_t x; /* random regular mpfr float */
885  double y; /* regular double float (equal to x) */
886
887  char flag[] =
888    {
889      '-',
890      '+',
891      ' ',
892      '#',
893      '0', /* no ambiguity: first zeros are flag zero*/
894      '\''
895    };
896  /* no 'a': mpfr and glibc do not have the same semantic */
897  char specifier[] =
898    {
899      'e',
900      'f',
901      'g',
902      'E',
903      'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for
904              regular numbers */
905      'G',
906    };
907  int spec; /* random index in specifier[] */
908  int prec; /* random value for precision field */
909
910  /* in the format string for mpfr_t variable, the maximum length is
911     reached by something like "%-+ #0'.*Rf", that is 12 characters. */
912#define FMT_MPFR_SIZE 12
913  char fmt_mpfr[FMT_MPFR_SIZE];
914  char *ptr_mpfr;
915
916  /* in the format string for double variable, the maximum length is
917     reached by something like "%-+ #0'.*f", that is 11 characters. */
918#define FMT_SIZE 11
919  char fmt[FMT_SIZE];
920  char *ptr;
921
922  int xi;
923  char *xs;
924  int yi;
925  char *ys;
926
927  int i, j, jmax;
928
929  mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
930
931  for (i = 0; i < 1000; ++i)
932    {
933      /* 1. random double */
934      do
935        {
936          y = DBL_RAND ();
937        }
938#ifdef HAVE_DENORMS
939      while (0);
940#else
941      while (ABS(y) < DBL_MIN);
942#endif
943
944      if (randlimb () % 2 == 0)
945        y = -y;
946
947      mpfr_set_d (x, y, MPFR_RNDN);
948      if (y != mpfr_get_d (x, MPFR_RNDN))
949        /* conversion error: skip this one */
950        continue;
951
952      /* 2. build random format strings fmt_mpfr and fmt */
953      ptr_mpfr = fmt_mpfr;
954      ptr = fmt;
955      *ptr_mpfr++ = *ptr++ = '%';
956      /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */
957      spec = (int) (randlimb() % 6);
958      /* random flags, but no ' flag with %e */
959      jmax = (spec == 0 || spec == 3) ? 5 : 6;
960      for (j = 0; j < jmax; j++)
961        {
962          if (randlimb() % 3 == 0)
963            *ptr_mpfr++ = *ptr++ = flag[j];
964        }
965      *ptr_mpfr++ = *ptr++ = '.';
966      *ptr_mpfr++ = *ptr++ = '*';
967      *ptr_mpfr++ = 'R';
968      *ptr_mpfr++ = *ptr++ = specifier[spec];
969      *ptr_mpfr = *ptr = '\0';
970      MPFR_ASSERTN (ptr - fmt < FMT_SIZE);
971      MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE);
972
973      /* advantage small precision */
974      if (randlimb() % 2 == 0)
975        prec = (int) (randlimb() % 10);
976      else
977        prec = (int) (randlimb() % prec_max_printf);
978
979      /* 3. calls and checks */
980      /* the double float case is handled by the libc asprintf through
981         gmp_asprintf */
982      xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x);
983      yi = mpfr_asprintf (&ys, fmt, prec, y);
984
985      /* test if XS and YS differ, beware that ISO C99 doesn't specify
986         the sign of a zero exponent (the C99 rationale says: "The sign
987         of a zero exponent in %e format is unspecified.  The committee
988         knows of different implementations and choose not to require
989         implementations to document their behaviour in this case
990         (by making this be implementation defined behaviour).  Most
991         implementations use a "+" sign, e.g., 1.2e+00; but there is at
992         least one implementation that uses the sign of the unlimited
993         precision result, e.g., the 0.987 would be 9.87e-01, so could
994         end up as 1e-00 after rounding to one digit of precision."),
995         while mpfr always uses '+' */
996      if (xi != yi
997          || ((strcmp (xs, ys) != 0)
998              && (spec == 1 || spec == 4
999                  || ((strstr (xs, "e+00") == NULL
1000                       || strstr (ys, "e-00") == NULL)
1001                      && (strstr (xs, "E+00") == NULL
1002                          || strstr (ys, "E-00") == NULL)))))
1003        {
1004          mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n",
1005                       fmt_mpfr, prec, x);
1006          printf ("expected: %s\n", ys);
1007          printf ("     got: %s\n", xs);
1008          printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec);
1009
1010          exit (1);
1011        }
1012
1013      mpfr_free_str (xs);
1014      mpfr_free_str (ys);
1015    }
1016
1017  mpfr_clear (x);
1018  return 0;
1019}
1020
1021static void
1022bug20080610 (void)
1023{
1024  /* bug on icc found on June 10, 2008 */
1025  /* this is not a bug but a different implementation choice: ISO C99 doesn't
1026     specify the sign of a zero exponent (see note in random_double above). */
1027  mpfr_t x;
1028  double y;
1029  int xi;
1030  char *xs;
1031  int yi;
1032  char *ys;
1033
1034  mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
1035
1036  y = -9.95645044213728791504536275169812142849e-01;
1037  mpfr_set_d (x, y, MPFR_RNDN);
1038
1039  xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x);
1040  yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y);
1041
1042  if (xi != yi || strcmp (xs, ys) != 0)
1043    {
1044      printf ("Error in bug20080610\n");
1045      printf ("expected: %s\n", ys);
1046      printf ("     got: %s\n", xs);
1047      printf ("xi=%d yi=%d\n", xi, yi);
1048
1049      exit (1);
1050    }
1051
1052  mpfr_free_str (xs);
1053  mpfr_free_str (ys);
1054  mpfr_clear (x);
1055}
1056
1057static void
1058bug20081214 (void)
1059{
1060 /* problem with glibc 2.3.6, December 14, 2008:
1061    the system asprintf outputs "-1.0" instead of "-1.". */
1062  mpfr_t x;
1063  double y;
1064  int xi;
1065  char *xs;
1066  int yi;
1067  char *ys;
1068
1069  mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
1070
1071  y = -9.90597761233942053494e-01;
1072  mpfr_set_d (x, y, MPFR_RNDN);
1073
1074  xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x);
1075  yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y);
1076
1077  if (xi != yi || strcmp (xs, ys) != 0)
1078    {
1079      mpfr_printf ("Error in bug20081214\n"
1080                   "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x);
1081      printf ("expected: %s\n", ys);
1082      printf ("     got: %s\n", xs);
1083      printf ("xi=%d yi=%d\n", xi, yi);
1084
1085      exit (1);
1086    }
1087
1088  mpfr_free_str (xs);
1089  mpfr_free_str (ys);
1090  mpfr_clear (x);
1091}
1092
1093static void
1094bug20111102 (void)
1095{
1096  mpfr_t t;
1097  char s[100];
1098
1099  mpfr_init2 (t, 84);
1100  mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN);
1101  mpfr_sprintf (s, "%.20RNg", t);
1102  if (strcmp (s, "1000") != 0)
1103    {
1104      printf ("Error in bug20111102, expected 1000, got %s\n", s);
1105      exit (1);
1106    }
1107  mpfr_clear (t);
1108}
1109
1110/* In particular, the following test makes sure that the rounding
1111 * for %Ra and %Rb is not done on the MPFR number itself (as it
1112 * would overflow). Note: it has been reported on comp.std.c that
1113 * some C libraries behave differently on %a, but this is a bug.
1114 */
1115static void
1116check_emax_aux (mpfr_exp_t e)
1117{
1118  mpfr_t x;
1119  char *s1, s2[256];
1120  int i;
1121  mpfr_exp_t emax;
1122
1123  MPFR_ASSERTN (e <= LONG_MAX);
1124  emax = mpfr_get_emax ();
1125  set_emax (e);
1126
1127  mpfr_init2 (x, 16);
1128
1129  mpfr_set_inf (x, 1);
1130  mpfr_nextbelow (x);
1131
1132  i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x);
1133  MPFR_ASSERTN (i > 0);
1134
1135  mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3);
1136
1137  if (strcmp (s1, s2) != 0)
1138    {
1139      printf ("Error in check_emax_aux for emax = ");
1140      if (e > LONG_MAX)
1141        printf ("(>LONG_MAX)\n");
1142      else
1143        printf ("%ld\n", (long) e);
1144      printf ("Expected %s\n", s2);
1145      printf ("Got      %s\n", s1);
1146      exit (1);
1147    }
1148
1149  mpfr_free_str (s1);
1150
1151  i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x);
1152  MPFR_ASSERTN (i > 0);
1153
1154  mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e);
1155
1156  if (strcmp (s1, s2) != 0)
1157    {
1158      printf ("Error in check_emax_aux for emax = ");
1159      if (e > LONG_MAX)
1160        printf ("(>LONG_MAX)\n");
1161      else
1162        printf ("%ld\n", (long) e);
1163      printf ("Expected %s\n", s2);
1164      printf ("Got      %s\n", s1);
1165      exit (1);
1166    }
1167
1168  mpfr_free_str (s1);
1169
1170  mpfr_clear (x);
1171  set_emax (emax);
1172}
1173
1174static void
1175check_emax (void)
1176{
1177  check_emax_aux (15);
1178  check_emax_aux (MPFR_EMAX_MAX);
1179}
1180
1181int
1182main (int argc, char **argv)
1183{
1184  char *locale;
1185
1186  tests_start_mpfr ();
1187
1188#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
1189  /* currently, we just check with 'C' locale */
1190  locale = setlocale (LC_ALL, "C");
1191#endif
1192
1193  bug20111102 ();
1194  native_types ();
1195  hexadecimal ();
1196  binary ();
1197  decimal ();
1198  mixed ();
1199  check_emax ();
1200
1201#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
1202  locale_da_DK ();
1203
1204  setlocale (LC_ALL, locale);
1205#endif
1206
1207  if (getenv ("MPFR_CHECK_LIBC_PRINTF"))
1208    {
1209      /* check against libc */
1210      random_double ();
1211      bug20081214 ();
1212      bug20080610 ();
1213    }
1214
1215  tests_end_mpfr ();
1216  return 0;
1217}
1218
1219#else  /* MPFR_VERSION */
1220
1221int
1222main (void)
1223{
1224  printf ("Warning! Test disabled for this MPFR version.\n");
1225  return 0;
1226}
1227
1228#endif  /* MPFR_VERSION */
1229
1230#else  /* HAVE_STDARG */
1231
1232int
1233main (void)
1234{
1235  /* We have nothing to test. */
1236  return 77;
1237}
1238
1239#endif  /* HAVE_STDARG */
1240