1/* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf,
2   and mpfr_vsnprintf
3
4Copyright 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5Contributed by the Arenaire and Cacao projects, INRIA.
6
7The GNU MPFR Library is free software; you can redistribute it and/or modify
8it under the terms of the GNU Lesser General Public License as published by
9the Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12The GNU MPFR Library is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15License for more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
19http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2051 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
36const int prec_max_printf = 5000; /* limit for random precision in
37                                     random_double() */
38#define BUF_SIZE 65536
39
40const char pinf_str[] = "inf";
41const char pinf_uc_str[] = "INF";
42const char minf_str[] = "-inf";
43const char minf_uc_str[] = "-INF";
44const char nan_str[] = "nan";
45const 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. */
50static int
51check_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. */
105static int
106check_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
168static void
169native_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
213static int
214decimal (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
508static int
509hexadecimal (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
651static int
652binary (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
730static int
731mixed (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. */
786static int
787locale_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 */
831static int
832random_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
971static void
972bug20080610 (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
1007static void
1008bug20081214 (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 */
1048static void
1049check_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
1099static void
1100check_emax (void)
1101{
1102  check_emax_aux (15);
1103  check_emax_aux (MPFR_EMAX_MAX);
1104}
1105
1106int
1107main (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
1145int
1146main (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
1156int
1157main (void)
1158{
1159  /* We have nothing to test. */
1160  return 0;
1161}
1162
1163#endif  /* HAVE_STDARG */
1164