Home | History | Annotate | Line # | Download | only in tests
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