Home | History | Annotate | Line # | Download | only in tests
tsprintf.c revision 1.1.1.6
      1 /* tsprintf.c -- test file for mpfr_sprintf, mpfr_vsprintf, mpfr_snprintf,
      2    and mpfr_vsnprintf
      3 
      4 Copyright 2007-2023 Free Software Foundation, Inc.
      5 Contributed by the AriC and Caramba projects, INRIA.
      6 
      7 This file is part of the GNU MPFR Library.
      8 
      9 The GNU MPFR Library is free software; you can redistribute it and/or modify
     10 it under the terms of the GNU Lesser General Public License as published by
     11 the Free Software Foundation; either version 3 of the License, or (at your
     12 option) any later version.
     13 
     14 The GNU MPFR Library is distributed in the hope that it will be useful, but
     15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     17 License for more details.
     18 
     19 You should have received a copy of the GNU Lesser General Public License
     20 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     23 
     24 /* Note: If you use a C99-compatible implementation and GMP (or MPIR)
     25  * has been compiled without HAVE_VSNPRINTF defined, then this test
     26  * may fail with an error like
     27  *   repl-vsnprintf.c:389: GNU MP assertion failed: len < total_width
     28  *
     29  * The reason is that __gmp_replacement_vsnprintf does not support %a/%A,
     30  * even though the C library supports it.
     31  *
     32  * References:
     33  *   https://sympa.inria.fr/sympa/arc/mpfr/2022-10/msg00001.html
     34  *   https://sympa.inria.fr/sympa/arc/mpfr/2022-10/msg00027.html
     35  *   https://gmplib.org/list-archives/gmp-bugs/2022-October/005200.html
     36  */
     37 
     38 /* Needed due to the tests on HAVE_STDARG and MPFR_USE_MINI_GMP */
     39 #ifdef HAVE_CONFIG_H
     40 # include "config.h"
     41 #endif
     42 
     43 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
     44 #include <stdarg.h>
     45 
     46 #include <float.h>
     47 #include <errno.h>
     48 
     49 #ifdef HAVE_LOCALE_H
     50 #include <locale.h>
     51 #endif
     52 
     53 #include "mpfr-test.h"
     54 
     55 const int prec_max_printf = 5000; /* limit for random precision in
     56                                      random_double() */
     57 #define BUF_SIZE 65536
     58 
     59 const char pinf_str[] = "inf";
     60 const char pinf_uc_str[] = "INF";
     61 const char minf_str[] = "-inf";
     62 const char minf_uc_str[] = "-INF";
     63 const char nan_str[] = "nan";
     64 const char nan_uc_str[] = "NAN";
     65 
     66 int randsize;
     67 
     68 /* 1. compare expected string with the string BUFFER returned by
     69    mpfr_sprintf(buffer, fmt, x)
     70    2. then test mpfr_snprintf (buffer, p, fmt, x) with a random p. */
     71 static void
     72 check_sprintf (const char *expected, const char *fmt, mpfr_srcptr x)
     73 {
     74   int n0, n1;
     75   char buffer[BUF_SIZE];
     76 
     77   /* test mpfr_sprintf */
     78   n0 = mpfr_sprintf (buffer, fmt, x);
     79   if (strcmp (buffer, expected) != 0)
     80     {
     81       printf ("Error in mpfr_sprintf (s, \"%s\", x);\n", fmt);
     82       printf ("expected: \"%s\"\ngot:      \"%s\"\n", expected, buffer);
     83 
     84       exit (1);
     85     }
     86 
     87   /* test mpfr_snprintf */
     88   randsize = (int) (randlimb () % (n0 + 3)) - 3;  /* between -3 and n0 - 1 */
     89   if (randsize < 0)
     90     {
     91       n1 = mpfr_snprintf (NULL, 0, fmt, x);
     92     }
     93   else
     94     {
     95       buffer[randsize] = 17;
     96       n1 = mpfr_snprintf (buffer, randsize, fmt, x);
     97       if (buffer[randsize] != 17)
     98         {
     99           printf ("Buffer overflow in mpfr_snprintf for randsize = %d!\n",
    100                   randsize);
    101           exit (1);
    102         }
    103     }
    104   if (n0 != n1)
    105     {
    106       printf ("Error in mpfr_snprintf (s, %d, \"%s\", x) return value\n",
    107               randsize, fmt);
    108       printf ("expected: %d\ngot:      %d\nx='", n0, n1);
    109       mpfr_printf (fmt, x);
    110       printf ("'\n");
    111       exit (1);
    112     }
    113   if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0)
    114       || (randsize == 1 && buffer[0] != '\0'))
    115     {
    116       char part_expected[BUF_SIZE];
    117       strncpy (part_expected, expected, randsize);
    118       part_expected[randsize - 1] = '\0';
    119       printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n",
    120               randsize, fmt);
    121       printf ("expected: \"%s\"\ngot:      \"%s\"\n", part_expected, buffer);
    122       exit (1);
    123     }
    124 }
    125 
    126 /* 1. compare expected string with the string BUFFER returned by
    127    mpfr_vsprintf(buffer, fmt, ...)
    128    2. then, test mpfr_vsnprintf. */
    129 static int
    130 check_vsprintf (const char *expected, const char *fmt, ...)
    131 {
    132   int n0, n1;
    133   char buffer[BUF_SIZE];
    134   va_list ap0, ap1;
    135 
    136   va_start (ap0, fmt);
    137   n0 = mpfr_vsprintf (buffer, fmt, ap0);
    138   va_end (ap0);
    139 
    140   if (strcmp (buffer, expected) != 0)
    141     {
    142       printf ("Error in mpfr_vsprintf (s, \"%s\", ...);\n", fmt);
    143       printf ("expected: \"%s\"\ngot:      \"%s\"\n", expected, buffer);
    144       exit (1);
    145     }
    146 
    147   va_start (ap1, fmt);
    148 
    149   /* test mpfr_snprintf */
    150   randsize = (int) (randlimb () % (n0 + 3)) - 3;  /* between -3 and n0 - 1 */
    151   if (randsize < 0)
    152     {
    153       n1 = mpfr_vsnprintf (NULL, 0, fmt, ap1);
    154     }
    155   else
    156     {
    157       buffer[randsize] = 17;
    158       n1 = mpfr_vsnprintf (buffer, randsize, fmt, ap1);
    159       if (buffer[randsize] != 17)
    160         {
    161           printf ("Buffer overflow in mpfr_vsnprintf for randsize = %d!\n",
    162                   randsize);
    163           exit (1);
    164         }
    165     }
    166 
    167   va_end (ap1);
    168 
    169   if (n0 != n1)
    170     {
    171       printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...) return value\n",
    172               randsize, fmt);
    173       printf ("expected: %d\ngot:      %d\n", n0, n1);
    174       exit (1);
    175     }
    176   if ((randsize > 1 && strncmp (expected, buffer, randsize - 1) != 0)
    177       || (randsize == 1 && buffer[0] != '\0'))
    178     {
    179       char part_expected[BUF_SIZE];
    180 
    181       strncpy (part_expected, expected, randsize);
    182       part_expected[randsize - 1] = '\0';
    183       printf ("Error in mpfr_vsnprintf (s, %d, \"%s\", ...);\n",
    184               randsize, fmt);
    185       printf ("expected: \"%s\"\ngot:      \"%s\"\n", part_expected, buffer);
    186       exit (1);
    187     }
    188 
    189   return n0;
    190 }
    191 
    192 static void
    193 native_types (void)
    194 {
    195   int c = 'a';
    196   int i = -1;
    197   unsigned int ui = 1;
    198   double d[] = { -1.25, 7.62939453125e-6 /* 2^(-17) */ };
    199   char s[] = "test";
    200   char buf[255];
    201   int k;
    202 
    203   sprintf (buf, "%c", c);
    204   check_vsprintf (buf, "%c", c);
    205 
    206   sprintf (buf, "%d", i);
    207   check_vsprintf (buf, "%d", i);
    208 
    209   check_vsprintf ("0", "%d", 0);
    210   check_vsprintf ("", "%.d", 0);
    211   check_vsprintf ("", "%.0d", 0);
    212 
    213   sprintf (buf, "%i", i);
    214   check_vsprintf (buf, "%i", i);
    215 
    216   check_vsprintf ("0", "%i", 0);
    217   check_vsprintf ("", "%.i", 0);
    218   check_vsprintf ("", "%.0i", 0);
    219 
    220   for (k = 0; k < numberof(d); k++)
    221     {
    222       sprintf (buf, "%e", d[k]);
    223       check_vsprintf (buf, "%e", d[k]);
    224 
    225       sprintf (buf, "%E", d[k]);
    226       check_vsprintf (buf, "%E", d[k]);
    227 
    228       sprintf (buf, "%f", d[k]);
    229       check_vsprintf (buf, "%f", d[k]);
    230 
    231       sprintf (buf, "%g", d[k]);
    232       check_vsprintf (buf, "%g", d[k]);
    233 
    234       sprintf (buf, "%G", d[k]);
    235       check_vsprintf (buf, "%G", d[k]);
    236 
    237 #if __MPFR_STDC (199901L)
    238 
    239       gmp_sprintf (buf, "%a", d[k]);
    240       check_vsprintf (buf, "%a", d[k]);
    241 
    242       gmp_sprintf (buf, "%A", d[k]);
    243       check_vsprintf (buf, "%A", d[k]);
    244 
    245       gmp_sprintf (buf, "%la", d[k]);
    246       check_vsprintf (buf, "%la", d[k]);
    247 
    248       gmp_sprintf (buf, "%lA", d[k]);
    249       check_vsprintf (buf, "%lA", d[k]);
    250 
    251       sprintf (buf, "%le", d[k]);
    252       check_vsprintf (buf, "%le", d[k]);
    253 
    254       sprintf (buf, "%lE", d[k]);
    255       check_vsprintf (buf, "%lE", d[k]);
    256 
    257       sprintf (buf, "%lf", d[k]);
    258       check_vsprintf (buf, "%lf", d[k]);
    259 
    260       sprintf (buf, "%lg", d[k]);
    261       check_vsprintf (buf, "%lg", d[k]);
    262 
    263       sprintf (buf, "%lG", d[k]);
    264       check_vsprintf (buf, "%lG", d[k]);
    265 
    266 #endif
    267     }
    268 
    269   sprintf (buf, "%o", i);
    270   check_vsprintf (buf, "%o", i);
    271 
    272   sprintf (buf, "%s", s);
    273   check_vsprintf (buf, "%s", s);
    274 
    275   sprintf (buf, "--%s++", "");
    276   check_vsprintf (buf, "--%s++", "");
    277 
    278   sprintf (buf, "%u", ui);
    279   check_vsprintf (buf, "%u", ui);
    280 
    281   sprintf (buf, "%x", ui);
    282   check_vsprintf (buf, "%x", ui);
    283 }
    284 
    285 static void
    286 decimal (void)
    287 {
    288   mpfr_prec_t p = 128;
    289   mpfr_t x, y, z;
    290 
    291   /* specifier 'P' for precision */
    292   check_vsprintf ("128", "%Pu", p);
    293   check_vsprintf ("00128", "%.5Pu", p);
    294   check_vsprintf ("  128", "%5Pu", p);
    295   check_vsprintf ("000128", "%06Pu", p);
    296   check_vsprintf ("128    :", "%-7Pu:", p);
    297   check_vsprintf ("000128:", "%-2.6Pd:", p);
    298   check_vsprintf ("  000128:", "%8.6Pd:", p);
    299   check_vsprintf ("000128  :", "%-8.6Pd:", p);
    300   check_vsprintf ("+128:", "%+Pd:", p);
    301   check_vsprintf (" 128:", "% Pd:", p);
    302   check_vsprintf ("80:", "% Px:", p);
    303   check_vsprintf ("0x80:", "% #Px:", p);
    304   check_vsprintf ("0x80:", "%0#+ -Px:", p);
    305   check_vsprintf ("0200:", "%0#+ -Po:", p);
    306   check_vsprintf ("+0000128 :", "%0+ *.*Pd:", -9, 7, p);
    307   check_vsprintf ("+12345   :", "%0+ -*.*Pd:", -9, -3, (mpfr_prec_t) 12345);
    308   check_vsprintf ("0", "%Pu", (mpfr_prec_t) 0);
    309   /* Do not add a test like "%05.1Pd" as MS Windows is buggy: when
    310      a precision is given, the '0' flag must be ignored. */
    311 
    312   /* specifier 'P' with precision field 0 */
    313   check_vsprintf ("128", "%.Pu", p);
    314   check_vsprintf ("128", "%.0Pd", p);
    315   check_vsprintf ("", "%.Pu", (mpfr_prec_t) 0);
    316   check_vsprintf ("", "%.0Pd", (mpfr_prec_t) 0);
    317 
    318   mpfr_init (z);
    319   mpfr_init2 (x, 128);
    320 
    321   /* special numbers */
    322   mpfr_set_inf (x, 1);
    323   check_sprintf (pinf_str, "%Re", x);
    324   check_sprintf (pinf_str, "%RUe", x);
    325   check_sprintf (pinf_uc_str, "%RE", x);
    326   check_sprintf (pinf_uc_str, "%RDE", x);
    327   check_sprintf (pinf_str, "%Rf", x);
    328   check_sprintf (pinf_str, "%RYf", x);
    329   check_sprintf (pinf_uc_str, "%RF", x);
    330   check_sprintf (pinf_uc_str, "%RZF", x);
    331   check_sprintf (pinf_str, "%Rg", x);
    332   check_sprintf (pinf_str, "%RNg", x);
    333   check_sprintf (pinf_uc_str, "%RG", x);
    334   check_sprintf (pinf_uc_str, "%RUG", x);
    335   check_sprintf ("       inf", "%010Re", x);
    336   check_sprintf ("       inf", "%010RDe", x);
    337 
    338   mpfr_set_inf (x, -1);
    339   check_sprintf (minf_str, "%Re", x);
    340   check_sprintf (minf_str, "%RYe", x);
    341   check_sprintf (minf_uc_str, "%RE", x);
    342   check_sprintf (minf_uc_str, "%RZE", x);
    343   check_sprintf (minf_str, "%Rf", x);
    344   check_sprintf (minf_str, "%RNf", x);
    345   check_sprintf (minf_uc_str, "%RF", x);
    346   check_sprintf (minf_uc_str, "%RUF", x);
    347   check_sprintf (minf_str, "%Rg", x);
    348   check_sprintf (minf_str, "%RDg", x);
    349   check_sprintf (minf_uc_str, "%RG", x);
    350   check_sprintf (minf_uc_str, "%RYG", x);
    351   check_sprintf ("      -inf", "%010Re", x);
    352   check_sprintf ("      -inf", "%010RZe", x);
    353 
    354   mpfr_set_nan (x);
    355   check_sprintf (nan_str, "%Re", x);
    356   check_sprintf (nan_str, "%RNe", x);
    357   check_sprintf (nan_uc_str, "%RE", x);
    358   check_sprintf (nan_uc_str, "%RUE", x);
    359   check_sprintf (nan_str, "%Rf", x);
    360   check_sprintf (nan_str, "%RDf", x);
    361   check_sprintf (nan_uc_str, "%RF", x);
    362   check_sprintf (nan_uc_str, "%RYF", x);
    363   check_sprintf (nan_str, "%Rg", x);
    364   check_sprintf (nan_str, "%RZg", x);
    365   check_sprintf (nan_uc_str, "%RG", x);
    366   check_sprintf (nan_uc_str, "%RNG", x);
    367   check_sprintf ("       nan", "%010Re", x);
    368 
    369   /* positive numbers */
    370   mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
    371   mpfr_init2 (y, 59);
    372   mpfr_set (y, x, MPFR_RNDN);
    373   mpfr_set_ui (z, 0, MPFR_RNDD);
    374 
    375   /* simplest case right justified */
    376   check_sprintf ("1.899347461279296875000000000000000000000e+07", "%30Re", x);
    377   check_sprintf ("      1.899347461279296875e+07", "%30Re", y);
    378   check_sprintf ("                         2e+07", "%30.0Re", x);
    379   check_sprintf ("               18993474.612793", "%30Rf", x);
    380   check_sprintf ("              18993474.6127930", "%30.7Rf", x);
    381   check_sprintf ("                   1.89935e+07", "%30Rg", x);
    382   check_sprintf ("                         2e+07", "%30.0Rg", x);
    383   check_sprintf ("          18993474.61279296875", "%30.19Rg", x);
    384   check_sprintf ("        0.0000000000000000e+00", "%30Re", z);
    385   check_sprintf ("                      0.000000", "%30Rf", z);
    386   check_sprintf ("                             0", "%30Rg", z);
    387   check_sprintf ("                       0.00000", "%#30Rg", z);
    388   check_sprintf ("                         0e+00", "%30.0Re", z);
    389   check_sprintf ("                             0", "%30.0Rf", z);
    390   check_sprintf ("                        0.0000", "%30.4Rf", z);
    391   check_sprintf ("                             0", "%30.0Rg", z);
    392   check_sprintf ("                             0", "%30.4Rg", z);
    393   /* sign or space, pad with leading zeros */
    394   check_sprintf (" 1.899347461279296875000000000000000000000E+07", "% 030RE", x);
    395   check_sprintf (" 000001.899347461279296875E+07", "% 030RE", y);
    396   check_sprintf (" 0000000000000000001.89935E+07", "% 030RG", x);
    397   check_sprintf (" 0000000000000000000000002E+07", "% 030.0RE", x);
    398   check_sprintf (" 0000000000000000000000000E+00", "% 030.0RE", z);
    399   check_sprintf (" 00000000000000000000000000000", "% 030.0RF", z);
    400   /* sign + or -, left justified */
    401   check_sprintf ("+1.899347461279296875000000000000000000000e+07", "%+-30Re", x);
    402   check_sprintf ("+1.899347461279296875e+07     ", "%+-30Re", y);
    403   check_sprintf ("+2e+07                        ", "%+-30.0Re", x);
    404   check_sprintf ("+0e+00                        ", "%+-30.0Re", z);
    405   check_sprintf ("+0                            ", "%+-30.0Rf", z);
    406   /* decimal point, left justified, precision and rounding parameter */
    407   check_vsprintf ("1.9E+07   ", "%#-10.*R*E", 1, MPFR_RNDN, x);
    408   check_vsprintf ("2.E+07    ", "%#*.*R*E", -10, 0, MPFR_RNDN, x);
    409   check_vsprintf ("2.E+07    ", "%#-10.*R*G", 0, MPFR_RNDN, x);
    410   check_vsprintf ("0.E+00    ", "%#-10.*R*E", 0, MPFR_RNDN, z);
    411   check_vsprintf ("0.        ", "%#-10.*R*F", 0, MPFR_RNDN, z);
    412   check_vsprintf ("0.        ", "%#-10.*R*G", 0, MPFR_RNDN, z);
    413   /* sign or space */
    414   check_sprintf (" 1.899e+07", "% .3RNe", x);
    415   check_sprintf (" 2e+07",     "% .0RNe", x);
    416   /* sign + or -, decimal point, pad with leading zeros */
    417   check_sprintf ("+0001.8E+07", "%0+#11.1RZE", x);
    418   check_sprintf ("+00001.E+07", "%0+#11.0RZE", x);
    419   check_sprintf ("+0000.0E+00", "%0+#11.1RZE", z);
    420   check_sprintf ("+00000000.0", "%0+#11.1RZF", z);
    421   /* pad with leading zero */
    422   check_sprintf ("1.899347461279296875000000000000000000000e+07", "%030RDe", x);
    423   check_sprintf ("0000001.899347461279296875e+07", "%030RDe", y);
    424   check_sprintf ("00000000000000000000000001e+07", "%030.0RDe", x);
    425   /* sign or space, decimal point, left justified */
    426   check_sprintf (" 1.8E+07   ", "%- #11.1RDE", x);
    427   check_sprintf (" 1.E+07    ", "%- #11.0RDE", x);
    428   /* large requested precision */
    429   check_sprintf ("18993474.61279296875", "%.2147483647Rg", x);
    430 
    431   /* negative numbers */
    432   mpfr_mul_si (x, x, -1, MPFR_RNDD);
    433   mpfr_mul_si (z, z, -1, MPFR_RNDD);
    434 
    435   /* sign + or - */
    436   check_sprintf ("  -1.8e+07", "%+10.1RUe", x);
    437   check_sprintf ("    -1e+07", "%+10.0RUe", x);
    438   check_sprintf ("    -0e+00", "%+10.0RUe", z);
    439   check_sprintf ("        -0", "%+10.0RUf", z);
    440 
    441   /* neighborhood of 1 */
    442   mpfr_set_str (x, "0.99993896484375", 10, MPFR_RNDN);
    443   mpfr_set_prec (y, 43);
    444   mpfr_set (y, x, MPFR_RNDN);
    445   check_sprintf ("9.999389648437500000000000000000000000000E-01", "%-20RE", x);
    446   check_sprintf ("9.9993896484375E-01 ", "%-20RE", y);
    447   check_sprintf ("1E+00               ", "%-20.RE", x);
    448   check_sprintf ("1E+00               ", "%-20.RE", y);
    449   check_sprintf ("1E+00               ", "%-20.0RE", x);
    450   check_sprintf ("1.0E+00             ", "%-20.1RE", x);
    451   check_sprintf ("1.00E+00            ", "%-20.2RE", x);
    452   check_sprintf ("9.999E-01           ", "%-20.3RE", x);
    453   check_sprintf ("9.9994E-01          ", "%-20.4RE", x);
    454   check_sprintf ("0.999939            ", "%-20RF", x);
    455   check_sprintf ("1                   ", "%-20.RF", x);
    456   check_sprintf ("1                   ", "%-20.0RF", x);
    457   check_sprintf ("1.0                 ", "%-20.1RF", x);
    458   check_sprintf ("1.00                ", "%-20.2RF", x);
    459   check_sprintf ("1.000               ", "%-20.3RF", x);
    460   check_sprintf ("0.9999              ", "%-20.4RF", x);
    461   check_sprintf ("0.999939            ", "%-#20RF", x);
    462   check_sprintf ("1.                  ", "%-#20.RF", x);
    463   check_sprintf ("1.                  ", "%-#20.0RF", x);
    464   check_sprintf ("1.0                 ", "%-#20.1RF", x);
    465   check_sprintf ("1.00                ", "%-#20.2RF", x);
    466   check_sprintf ("1.000               ", "%-#20.3RF", x);
    467   check_sprintf ("0.9999              ", "%-#20.4RF", x);
    468   check_sprintf ("0.999939            ", "%-20RG", x);
    469   check_sprintf ("1                   ", "%-20.RG", x);
    470   check_sprintf ("1                   ", "%-20.0RG", x);
    471   check_sprintf ("1                   ", "%-20.1RG", x);
    472   check_sprintf ("1                   ", "%-20.2RG", x);
    473   check_sprintf ("1                   ", "%-20.3RG", x);
    474   check_sprintf ("0.9999              ", "%-20.4RG", x);
    475   check_sprintf ("0.999939            ", "%-#20RG", x);
    476   check_sprintf ("1.                  ", "%-#20.RG", x);
    477   check_sprintf ("1.                  ", "%-#20.0RG", x);
    478   check_sprintf ("1.                  ", "%-#20.1RG", x);
    479   check_sprintf ("1.0                 ", "%-#20.2RG", x);
    480   check_sprintf ("1.00                ", "%-#20.3RG", x);
    481   check_sprintf ("0.9999              ", "%-#20.4RG", x);
    482 
    483   /* powers of 10 */
    484   mpfr_set_str (x, "1e17", 10, MPFR_RNDN);
    485   check_sprintf ("1.000000000000000000000000000000000000000e+17", "%Re", x);
    486   check_sprintf ("1.000e+17", "%.3Re", x);
    487   check_sprintf ("100000000000000000", "%.Rf", x);
    488   check_sprintf ("100000000000000000", "%.0Rf", x);
    489   check_sprintf ("100000000000000000.0", "%.1Rf", x);
    490   check_sprintf ("100000000000000000.000000", "%'Rf", x);
    491   check_sprintf ("100000000000000000.0", "%'.1Rf", x);
    492 
    493   mpfr_ui_div (x, 1, x, MPFR_RNDN); /* x=1e-17 */
    494   check_sprintf ("1.000000000000000000000000000000000000000e-17", "%Re", x);
    495   check_sprintf ("0.000000", "%Rf", x);
    496   check_sprintf ("1e-17", "%Rg", x);
    497   check_sprintf ("0.0", "%.1RDf", x);
    498   check_sprintf ("0.0", "%.1RZf", x);
    499   check_sprintf ("0.1", "%.1RUf", x);
    500   check_sprintf ("0.1", "%.1RYf", x);
    501   check_sprintf ("0", "%.0RDf", x);
    502   check_sprintf ("0", "%.0RZf", x);
    503   check_sprintf ("1", "%.0RUf", x);
    504   check_sprintf ("1", "%.0RYf", x);
    505 
    506   /* powers of 10 with 'g' style */
    507   mpfr_set_str (x, "10", 10, MPFR_RNDN);
    508   check_sprintf ("10", "%Rg", x);
    509   check_sprintf ("1e+01", "%.0Rg", x);
    510   check_sprintf ("1e+01", "%.1Rg", x);
    511   check_sprintf ("10", "%.2Rg", x);
    512 
    513   mpfr_ui_div (x, 1, x, MPFR_RNDN);
    514   check_sprintf ("0.1", "%Rg", x);
    515   check_sprintf ("0.1", "%.0Rg", x);
    516   check_sprintf ("0.1", "%.1Rg", x);
    517 
    518   mpfr_set_str (x, "1000", 10, MPFR_RNDN);
    519   check_sprintf ("1000", "%Rg", x);
    520   check_sprintf ("1e+03", "%.0Rg", x);
    521   check_sprintf ("1e+03", "%.3Rg", x);
    522   check_sprintf ("1000", "%.4Rg", x);
    523   check_sprintf ("1e+03", "%.3Rg", x);
    524   check_sprintf ("1000", "%.4Rg", x);
    525   check_sprintf ("    1e+03", "%9.3Rg", x);
    526   check_sprintf ("     1000", "%9.4Rg", x);
    527   check_sprintf ("00001e+03", "%09.3Rg", x);
    528   check_sprintf ("000001000", "%09.4Rg", x);
    529 
    530   mpfr_ui_div (x, 1, x, MPFR_RNDN);
    531   check_sprintf ("0.001", "%Rg", x);
    532   check_sprintf ("0.001", "%.0Rg", x);
    533   check_sprintf ("0.001", "%.1Rg", x);
    534 
    535   mpfr_set_str (x, "100000", 10, MPFR_RNDN);
    536   check_sprintf ("100000", "%Rg", x);
    537   check_sprintf ("1e+05", "%.0Rg", x);
    538   check_sprintf ("1e+05", "%.5Rg", x);
    539   check_sprintf ("100000", "%.6Rg", x);
    540   check_sprintf ("            1e+05", "%17.5Rg", x);
    541   check_sprintf ("           100000", "%17.6Rg", x);
    542   check_sprintf ("0000000000001e+05", "%017.5Rg", x);
    543   check_sprintf ("00000000000100000", "%017.6Rg", x);
    544 
    545   mpfr_ui_div (x, 1, x, MPFR_RNDN);
    546   check_sprintf ("1e-05", "%Rg", x);
    547   check_sprintf ("1e-05", "%.0Rg", x);
    548   check_sprintf ("1e-05", "%.1Rg", x);
    549 
    550   /* check rounding mode */
    551   mpfr_set_str (x, "0.0076", 10, MPFR_RNDN);
    552   check_sprintf ("0.007", "%.3RDF", x);
    553   check_sprintf ("0.007", "%.3RZF", x);
    554   check_sprintf ("0.008", "%.3RF", x);
    555   check_sprintf ("0.008", "%.3RUF", x);
    556   check_sprintf ("0.008", "%.3RYF", x);
    557   check_vsprintf ("0.008", "%.3R*F", MPFR_RNDA, x);
    558 
    559   /* check limit between %f-style and %g-style */
    560   mpfr_set_str (x, "0.0000999", 10, MPFR_RNDN);
    561   check_sprintf ("0.0001",   "%.0Rg", x);
    562   check_sprintf ("9e-05",    "%.0RDg", x);
    563   check_sprintf ("0.0001",   "%.1Rg", x);
    564   check_sprintf ("0.0001",   "%.2Rg", x);
    565   check_sprintf ("9.99e-05", "%.3Rg", x);
    566 
    567   /* trailing zeros */
    568   mpfr_set_si_2exp (x, -1, -15, MPFR_RNDN); /* x=-2^-15 */
    569   check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
    570   check_sprintf ("-3.051757812500000000000000000000e-05", "%.30Re", x);
    571   check_sprintf ("-3.05175781250000000000000000000e-05", "%#.30Rg", x);
    572   check_sprintf ("-0.000030517578125000000000000000", "%.30Rf", x);
    573 
    574   /* bug 20081023 */
    575   check_sprintf ("-3.0517578125e-05", "%.30Rg", x);
    576   mpfr_set_str (x, "1.9999", 10, MPFR_RNDN);
    577   check_sprintf ("1.999900  ", "%-#10.7RG", x);
    578   check_sprintf ("1.9999    ", "%-10.7RG", x);
    579   mpfr_set_ui (x, 1, MPFR_RNDN);
    580   check_sprintf ("1.", "%#.1Rg", x);
    581   check_sprintf ("1.   ", "%-#5.1Rg", x);
    582   check_sprintf ("  1.0", "%#5.2Rg", x);
    583   check_sprintf ("1.00000000000000000000000000000", "%#.30Rg", x);
    584   check_sprintf ("1", "%.30Rg", x);
    585   mpfr_set_ui (x, 0, MPFR_RNDN);
    586   check_sprintf ("0.", "%#.1Rg", x);
    587   check_sprintf ("0.   ", "%-#5.1Rg", x);
    588   check_sprintf ("  0.0", "%#5.2Rg", x);
    589   check_sprintf ("0.00000000000000000000000000000", "%#.30Rg", x);
    590   check_sprintf ("0", "%.30Rg", x);
    591 
    592   /* following tests with precision 53 bits */
    593   mpfr_set_prec (x, 53);
    594 
    595   /* Exponent zero has a plus sign */
    596   mpfr_set_str (x, "-9.95645044213728791504536275169812142849e-01", 10,
    597                 MPFR_RNDN);
    598   check_sprintf ("-1.0e+00", "%- #0.1Re", x);
    599 
    600   /* Decimal point and no figure after it with '#' flag and 'G' style */
    601   mpfr_set_str (x, "-9.90597761233942053494e-01", 10, MPFR_RNDN);
    602   check_sprintf ("-1.", "%- #0.1RG", x);
    603 
    604   /* precision zero */
    605   mpfr_set_d (x, 9.5, MPFR_RNDN);
    606   check_sprintf ("9",    "%.0RDf", x);
    607   check_sprintf ("10",    "%.0RUf", x);
    608 
    609   mpfr_set_d (x, 19.5, MPFR_RNDN);
    610   check_sprintf ("19",    "%.0RDf", x);
    611   check_sprintf ("20",    "%.0RUf", x);
    612 
    613   mpfr_set_d (x, 99.5, MPFR_RNDN);
    614   check_sprintf ("99",    "%.0RDf", x);
    615   check_sprintf ("100",   "%.0RUf", x);
    616 
    617   mpfr_set_d (x, -9.5, MPFR_RNDN);
    618   check_sprintf ("-10",    "%.0RDf", x);
    619   check_sprintf ("-10",    "%.0RYf", x);
    620   check_sprintf ("-10",    "%.0Rf", x);
    621   check_sprintf ("-1e+01", "%.0Re", x);
    622   check_sprintf ("-1e+01", "%.0Rg", x);
    623   mpfr_set_ui_2exp (x, 1, -1, MPFR_RNDN);
    624   check_sprintf ("0",      "%.0Rf", x);
    625   check_sprintf ("5e-01",  "%.0Re", x);
    626   check_sprintf ("0.5",    "%.0Rg", x);
    627   mpfr_set_ui_2exp (x, 3, -1, MPFR_RNDN);
    628   check_sprintf ("2",      "%.0Rf", x);
    629   mpfr_set_ui_2exp (x, 5, -1, MPFR_RNDN);
    630   check_sprintf ("2",      "%.0Rf", x);
    631   mpfr_set_ui (x, 0x1f, MPFR_RNDN);
    632   check_sprintf ("0x1p+5", "%.0Ra", x);
    633   mpfr_set_ui (x, 3, MPFR_RNDN);
    634   check_sprintf ("1p+2",   "%.0Rb", x);
    635 
    636   /* round to next ten power with %f but not with %g */
    637   mpfr_set_str (x, "-6.64464380544039223686e-02", 10, MPFR_RNDN);
    638   check_sprintf ("-0.1",  "%.1Rf", x);
    639   check_sprintf ("-0.0",  "%.1RZf", x);
    640   check_sprintf ("-0.07", "%.1Rg", x);
    641   check_sprintf ("-0.06", "%.1RZg", x);
    642 
    643   /* round to next ten power and do not remove trailing zeros */
    644   mpfr_set_str (x, "9.98429393291486722006e-02", 10, MPFR_RNDN);
    645   check_sprintf ("0.1",   "%#.1Rg", x);
    646   check_sprintf ("0.10",  "%#.2Rg", x);
    647   check_sprintf ("0.099", "%#.2RZg", x);
    648 
    649   /* Halfway cases */
    650   mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
    651   check_sprintf ("2e+00", "%.0Re", x);
    652   mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
    653   check_sprintf ("2e+00", "%.0Re", x);
    654   mpfr_set_str (x, "9.5", 10, MPFR_RNDN);
    655   check_sprintf ("1e+01", "%.0Re", x);
    656   mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
    657   check_sprintf ("1.2e+00", "%.1Re", x);
    658   mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
    659   check_sprintf ("1.8e+00", "%.1Re", x);
    660   mpfr_set_str (x, "-0.5", 10, MPFR_RNDN);
    661   check_sprintf ("-0", "%.0Rf", x);
    662   mpfr_set_str (x, "1.25", 10, MPFR_RNDN);
    663   check_sprintf ("1.2", "%.1Rf", x);
    664   mpfr_set_str (x, "1.75", 10, MPFR_RNDN);
    665   check_sprintf ("1.8", "%.1Rf", x);
    666   mpfr_set_str (x, "1.5", 10, MPFR_RNDN);
    667   check_sprintf ("2", "%.1Rg", x);
    668   mpfr_set_str (x, "2.5", 10, MPFR_RNDN);
    669   check_sprintf ("2", "%.1Rg", x);
    670   mpfr_set_str (x, "9.25", 10, MPFR_RNDN);
    671   check_sprintf ("9.2", "%.2Rg", x);
    672   mpfr_set_str (x, "9.75", 10, MPFR_RNDN);
    673   check_sprintf ("9.8", "%.2Rg", x);
    674 
    675   /* assertion failure in r6320 */
    676   mpfr_set_str (x, "-9.996", 10, MPFR_RNDN);
    677   check_sprintf ("-10.0", "%.1Rf", x);
    678 
    679   /* regression in MPFR 3.1.0 (bug introduced in r7761, fixed in r7931) */
    680   check_sprintf ("-10", "%.2Rg", x);
    681 
    682   mpfr_clears (x, y, z, (mpfr_ptr) 0);
    683 }
    684 
    685 static void
    686 hexadecimal (void)
    687 {
    688   mpfr_t x, z;
    689 
    690   mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
    691 
    692   /* special */
    693   mpfr_set_inf (x, 1);
    694   check_sprintf (pinf_str, "%Ra", x);
    695   check_sprintf (pinf_str, "%RUa", x);
    696   check_sprintf (pinf_str, "%RDa", x);
    697   check_sprintf (pinf_uc_str, "%RA", x);
    698   check_sprintf (pinf_uc_str, "%RYA", x);
    699   check_sprintf (pinf_uc_str, "%RZA", x);
    700   check_sprintf (pinf_uc_str, "%RNA", x);
    701 
    702   mpfr_set_inf (x, -1);
    703   check_sprintf (minf_str, "%Ra", x);
    704   check_sprintf (minf_str, "%RYa", x);
    705   check_sprintf (minf_str, "%RZa", x);
    706   check_sprintf (minf_str, "%RNa", x);
    707   check_sprintf (minf_uc_str, "%RA", x);
    708   check_sprintf (minf_uc_str, "%RUA", x);
    709   check_sprintf (minf_uc_str, "%RDA", x);
    710 
    711   mpfr_set_nan (x);
    712   check_sprintf (nan_str, "%Ra", x);
    713   check_sprintf (nan_uc_str, "%RA", x);
    714 
    715   /* regular numbers */
    716   mpfr_set_str (x, "FEDCBA9.87654321", 16, MPFR_RNDN);
    717   mpfr_set_ui (z, 0, MPFR_RNDZ);
    718 
    719   /* simplest case right justified */
    720   check_sprintf ("   0xf.edcba987654321p+24", "%25Ra", x);
    721   check_sprintf ("   0xf.edcba987654321p+24", "%25RUa", x);
    722   check_sprintf ("   0xf.edcba987654321p+24", "%25RDa", x);
    723   check_sprintf ("   0xf.edcba987654321p+24", "%25RYa", x);
    724   check_sprintf ("   0xf.edcba987654321p+24", "%25RZa", x);
    725   check_sprintf ("   0xf.edcba987654321p+24", "%25RNa", x);
    726   check_sprintf ("                  0x1p+28", "%25.0Ra", x);
    727   check_sprintf ("                   0x0p+0", "%25.0Ra", z);
    728   check_sprintf ("                   0x0p+0", "%25Ra", z);
    729   check_sprintf ("                  0x0.p+0", "%#25Ra", z);
    730   /* sign or space, pad with leading zeros */
    731   check_sprintf (" 0X00F.EDCBA987654321P+24", "% 025RA", x);
    732   check_sprintf (" 0X000000000000000001P+28", "% 025.0RA", x);
    733   check_sprintf (" 0X0000000000000000000P+0", "% 025.0RA", z);
    734   /* sign + or -, left justified */
    735   check_sprintf ("+0xf.edcba987654321p+24  ", "%+-25Ra", x);
    736   check_sprintf ("+0x1p+28                 ", "%+-25.0Ra", x);
    737   check_sprintf ("+0x0p+0                  ", "%+-25.0Ra", z);
    738   /* decimal point, left justified, precision and rounding parameter */
    739   check_vsprintf ("0XF.FP+24 ", "%#-10.*R*A", 1, MPFR_RNDN, x);
    740   check_vsprintf ("0X1.P+28  ", "%#-10.*R*A", 0, MPFR_RNDN, x);
    741   check_vsprintf ("0X0.P+0   ", "%#-10.*R*A", 0, MPFR_RNDN, z);
    742   /* sign or space */
    743   check_sprintf (" 0xf.eddp+24", "% .3RNa", x);
    744   check_sprintf (" 0x1p+28",     "% .0RNa", x);
    745   /* sign + or -, decimal point, pad with leading zeros */
    746   check_sprintf ("+0X0F.EP+24", "%0+#11.1RZA", x);
    747   check_sprintf ("+0X00F.P+24", "%0+#11.0RZA", x);
    748   check_sprintf ("+0X000.0P+0", "%0+#11.1RZA", z);
    749   /* pad with leading zero */
    750   check_sprintf ("0x0000f.edcba987654321p+24", "%026RDa", x);
    751   check_sprintf ("0x0000000000000000000fp+24", "%026.0RDa", x);
    752   /* sign or space, decimal point, left justified */
    753   check_sprintf (" 0XF.EP+24 ", "%- #11.1RDA", x);
    754   check_sprintf (" 0XF.P+24  ", "%- #11.0RDA", x);
    755 
    756   mpfr_mul_si (x, x, -1, MPFR_RNDD);
    757   mpfr_mul_si (z, z, -1, MPFR_RNDD);
    758 
    759   /* sign + or - */
    760   check_sprintf ("-0xf.ep+24", "%+10.1RUa", x);
    761   check_sprintf ("  -0xfp+24", "%+10.0RUa", x);
    762   check_sprintf ("   -0x0p+0", "%+10.0RUa", z);
    763 
    764   /* rounding bit is zero */
    765   mpfr_set_str (x, "0xF.7", 16, MPFR_RNDN);
    766   check_sprintf ("0XFP+0", "%.0RNA", x);
    767   /* tie case in round to nearest mode */
    768   mpfr_set_str (x, "0x0.8800000000000000p+3", 16, MPFR_RNDN);
    769   check_sprintf ("0x9.p-1", "%#.0RNa", x);
    770   mpfr_set_str (x, "-0x0.9800000000000000p+3", 16, MPFR_RNDN);
    771   check_sprintf ("-0xap-1", "%.0RNa", x);
    772   /* trailing zeros in fractional part */
    773   check_sprintf ("-0X4.C0000000000000000000P+0", "%.20RNA", x);
    774   /* rounding bit is one and the first non zero bit is far away */
    775   mpfr_set_prec (x, 1024);
    776   mpfr_set_ui_2exp (x, 29, -1, MPFR_RNDN);
    777   mpfr_nextabove (x);
    778   check_sprintf ("0XFP+0", "%.0RNA", x);
    779 
    780   /* with more than one limb */
    781   mpfr_set_prec (x, 300);
    782   mpfr_set_str (x, "0xf.ffffffffffffffffffffffffffffffffffffffffffffffffffff"
    783                 "fffffffffffffffff", 16, MPFR_RNDN);
    784   check_sprintf ("0x1p+4 [300]", "%.0RNa [300]", x);
    785   check_sprintf ("0xfp+0 [300]", "%.0RZa [300]", x);
    786   check_sprintf ("0x1p+4 [300]", "%.0RYa [300]", x);
    787   check_sprintf ("0xfp+0 [300]", "%.0RDa [300]", x);
    788   check_sprintf ("0x1p+4 [300]", "%.0RUa [300]", x);
    789   check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
    790                  "%.40RNa", x);
    791   check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
    792                  "%.40RZa", x);
    793   check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
    794                  "%.40RYa", x);
    795   check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffffffp+0",
    796                  "%.40RDa", x);
    797   check_sprintf ("0x1.0000000000000000000000000000000000000000p+4",
    798                  "%.40RUa", x);
    799 
    800   mpfr_set_str (x, "0xf.7fffffffffffffffffffffffffffffffffffffffffffffffffff"
    801                 "ffffffffffffffffff", 16, MPFR_RNDN);
    802   check_sprintf ("0XFP+0", "%.0RNA", x);
    803   check_sprintf ("0XFP+0", "%.0RZA", x);
    804   check_sprintf ("0X1P+4", "%.0RYA", x);
    805   check_sprintf ("0XFP+0", "%.0RDA", x);
    806   check_sprintf ("0X1P+4", "%.0RUA", x);
    807   check_sprintf ("0XF.8P+0", "%.1RNA", x);
    808   check_sprintf ("0XF.7P+0", "%.1RZA", x);
    809   check_sprintf ("0XF.8P+0", "%.1RYA", x);
    810   check_sprintf ("0XF.7P+0", "%.1RDA", x);
    811   check_sprintf ("0XF.8P+0", "%.1RUA", x);
    812 
    813   /* do not round up to the next power of the base */
    814   mpfr_set_str (x, "0xf.fffffffffffffffffffffffffffffffffffffeffffffffffffff"
    815                 "ffffffffffffffffff", 16, MPFR_RNDN);
    816   check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
    817                  "%.40RNa", x);
    818   check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
    819                  "%.40RZa", x);
    820   check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
    821                  "%.40RYa", x);
    822   check_sprintf ("0xf.fffffffffffffffffffffffffffffffffffffeffp+0",
    823                  "%.40RDa", x);
    824   check_sprintf ("0xf.ffffffffffffffffffffffffffffffffffffff00p+0",
    825                  "%.40RUa", x);
    826 
    827   mpfr_clears (x, z, (mpfr_ptr) 0);
    828 }
    829 
    830 static void
    831 binary (void)
    832 {
    833   mpfr_t x;
    834   mpfr_t z;
    835 
    836   mpfr_inits2 (64, x, z, (mpfr_ptr) 0);
    837 
    838   /* special */
    839   mpfr_set_inf (x, 1);
    840   check_sprintf (pinf_str, "%Rb", x);
    841 
    842   mpfr_set_inf (x, -1);
    843   check_sprintf (minf_str, "%Rb", x);
    844 
    845   mpfr_set_nan (x);
    846   check_sprintf (nan_str, "%Rb", x);
    847 
    848   /* regular numbers */
    849   mpfr_set_str (x, "1110010101.1001101", 2, MPFR_RNDN);
    850   mpfr_set_ui (z, 0, MPFR_RNDN);
    851 
    852   /* simplest case: right justified */
    853   check_sprintf ("    1.1100101011001101p+9", "%25Rb", x);
    854   check_sprintf ("                     0p+0", "%25Rb", z);
    855   check_sprintf ("                    0.p+0", "%#25Rb", z);
    856   /* sign or space, pad with leading zeros */
    857   check_sprintf (" 0001.1100101011001101p+9", "% 025Rb", x);
    858   check_sprintf (" 000000000000000000000p+0", "% 025Rb", z);
    859   /* sign + or -, left justified */
    860   check_sprintf ("+1.1100101011001101p+9   ", "%+-25Rb", x);
    861   check_sprintf ("+0p+0                    ", "%+-25Rb", z);
    862   /* sign or space */
    863   check_sprintf (" 1.110p+9",  "% .3RNb", x);
    864   check_sprintf (" 1.1101p+9", "% .4RNb", x);
    865   check_sprintf (" 0.0000p+0", "% .4RNb", z);
    866   /* sign + or -, decimal point, pad with leading zeros */
    867   check_sprintf ("+00001.1p+9", "%0+#11.1RZb", x);
    868   check_sprintf ("+0001.0p+10", "%0+#11.1RNb", x);
    869   check_sprintf ("+000000.p+0", "%0+#11.0RNb", z);
    870   /* pad with leading zero */
    871   check_sprintf ("00001.1100101011001101p+9", "%025RDb", x);
    872   /* sign or space, decimal point (unused), left justified */
    873   check_sprintf (" 1.1p+9    ", "%- #11.1RDb", x);
    874   check_sprintf (" 1.p+9     ", "%- #11.0RDb", x);
    875   check_sprintf (" 1.p+10    ", "%- #11.0RUb", x);
    876   check_sprintf (" 1.p+9     ", "%- #11.0RZb", x);
    877   check_sprintf (" 1.p+10    ", "%- #11.0RYb", x);
    878   check_sprintf (" 1.p+10    ", "%- #11.0RNb", x);
    879 
    880   mpfr_mul_si (x, x, -1, MPFR_RNDD);
    881   mpfr_mul_si (z, z, -1, MPFR_RNDD);
    882 
    883   /* sign + or - */
    884   check_sprintf ("   -1.1p+9", "%+10.1RUb", x);
    885   check_sprintf ("   -0.0p+0", "%+10.1RUb", z);
    886 
    887   /* precision 0 */
    888   check_sprintf ("-1p+10", "%.0RNb", x);
    889   check_sprintf ("-1p+10", "%.0RDb", x);
    890   check_sprintf ("-1p+9",  "%.0RUb", x);
    891   check_sprintf ("-1p+9",  "%.0RZb", x);
    892   check_sprintf ("-1p+10", "%.0RYb", x);
    893   /* round to next base power */
    894   check_sprintf ("-1.0p+10", "%.1RNb", x);
    895   check_sprintf ("-1.0p+10", "%.1RDb", x);
    896   check_sprintf ("-1.0p+10", "%.1RYb", x);
    897   /* do not round to next base power */
    898   check_sprintf ("-1.1p+9", "%.1RUb", x);
    899   check_sprintf ("-1.1p+9", "%.1RZb", x);
    900   /* rounding bit is zero */
    901   check_sprintf ("-1.11p+9", "%.2RNb", x);
    902   /* tie case in round to nearest mode */
    903   check_sprintf ("-1.1100101011001101p+9", "%.16RNb", x);
    904   /* trailing zeros in fractional part */
    905   check_sprintf ("-1.110010101100110100000000000000p+9", "%.30RNb", x);
    906 
    907   mpfr_clears (x, z, (mpfr_ptr) 0);
    908 }
    909 
    910 static void
    911 mixed (void)
    912 {
    913   int n1;
    914   int n2;
    915   int i = 121;
    916 #ifdef PRINTF_L
    917   long double d = 1. / 31.;
    918 #endif
    919   mpf_t mpf;
    920   mpq_t mpq;
    921   mpz_t mpz;
    922   mpfr_t x;
    923   mpfr_rnd_t rnd;
    924   int k;
    925 
    926   mpf_init (mpf);
    927   mpf_set_ui (mpf, 40);
    928   mpf_div_ui (mpf, mpf, 31); /* mpf = 40.0 / 31.0 */
    929   mpq_init (mpq);
    930   mpq_set_ui (mpq, 123456, 4567890);
    931   mpz_init (mpz);
    932   mpz_fib_ui (mpz, 64);
    933   mpfr_init (x);
    934   mpfr_set_str (x, "-12345678.875", 10, MPFR_RNDN);
    935   rnd = MPFR_RNDD;
    936 
    937   check_vsprintf ("121%", "%i%%", i);
    938   check_vsprintf ("121% -1.2345678875000000E+07", "%i%% %RNE", i, x);
    939   check_vsprintf ("121, -12345679", "%i, %.0Rf", i, x);
    940   check_vsprintf ("10610209857723, -1.2345678875000000e+07", "%Zi, %R*e", mpz, rnd,
    941                   x);
    942   check_vsprintf ("-12345678.9, 121", "%.1Rf, %i", x, i);
    943   check_vsprintf ("-12345678, 1e240/45b352", "%.0R*f, %Qx", MPFR_RNDZ, x, mpq);
    944 
    945   /* TODO: Systematically test with and without %n in check_vsprintf? */
    946   /* Do the test several times due to random parameters in check_vsprintf
    947      and the use of %n. In r11501, n2 is incorrect (seems random) when
    948      randsize <= 0, i.e. when the size argument of mpfr_vsnprintf is 0. */
    949   for (k = 0; k < 30; k++)
    950     {
    951       n2 = -17;
    952       /* If this value is obtained for n2 after the check_vsprintf call below,
    953          this probably means that n2 has not been written as expected. */
    954       n1 = check_vsprintf ("121, -12345678.875000000000, 1.290323",
    955                            "%i, %.*Rf, %Ff%n", i, 12, x, mpf, &n2);
    956       if (n1 != n2)
    957         {
    958           printf ("error in number of characters written by mpfr_vsprintf"
    959                   " for k = %d, randsize = %d\n", k, randsize);
    960           printf ("expected: %d\n", n2);
    961           printf ("     got: %d\n", n1);
    962           exit (1);
    963         }
    964     }
    965 
    966 #ifdef PRINTF_L
    967   /* under MinGW, -D__USE_MINGW_ANSI_STDIO is required to support %Lf
    968      see https://gcc.gnu.org/legacy-ml/gcc/2013-03/msg00103.html */
    969   check_vsprintf ("00000010610209857723, -1.2345678875000000e+07, 0.032258",
    970                   "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
    971 #endif
    972 
    973   /* check invalid spec.spec */
    974   check_vsprintf ("%,", "%,");
    975   check_vsprintf ("%3*Rg", "%3*Rg");
    976 
    977   /* check empty format */
    978   check_vsprintf ("%", "%");
    979 
    980   mpf_clear (mpf);
    981   mpq_clear (mpq);
    982   mpz_clear (mpz);
    983   mpfr_clear (x);
    984 }
    985 
    986 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
    987 
    988 /* Check with locale "da_DK.utf8" or "da_DK".
    989    On most platforms, decimal point is ',' and thousands separator is '.';
    990    if this is not the case or if the locale does not exist, the test is not
    991    performed (and if the MPFR_CHECK_LOCALES environment variable is set,
    992    the program fails). */
    993 static void
    994 locale_da_DK (void)
    995 {
    996   mpfr_prec_t p = 128;
    997   mpfr_t x, y;
    998 
    999   if ((setlocale (LC_ALL, "da_DK.utf8") == 0 &&
   1000        setlocale (LC_ALL, "da_DK") == 0) ||
   1001       localeconv()->decimal_point[0] != ',' ||
   1002       localeconv()->thousands_sep[0] != '.')
   1003     {
   1004       setlocale (LC_ALL, "C");
   1005 
   1006       if (getenv ("MPFR_CHECK_LOCALES") == NULL)
   1007         return;
   1008 
   1009       fprintf (stderr,
   1010                "Cannot test the da_DK locale (not found or inconsistent).\n");
   1011       exit (1);
   1012     }
   1013 
   1014   mpfr_init2 (x, p);
   1015 
   1016   /* positive numbers */
   1017   mpfr_set_str (x, "18993474.61279296875", 10, MPFR_RNDN);
   1018   mpfr_init2 (y, 59);
   1019   mpfr_set (y, x, MPFR_RNDN);
   1020 
   1021   /* simplest case right justified with thousands separator */
   1022   check_sprintf ("1,899347461279296875000000000000000000000e+07", "%'30Re", x);
   1023   check_sprintf ("      1,899347461279296875e+07", "%'30Re", y);
   1024   check_sprintf ("                   1,89935e+07", "%'30Rg", x);
   1025   check_sprintf ("        18.993.474,61279296875", "%'30.19Rg", x);
   1026   check_sprintf ("             18.993.474,612793", "%'30Rf", x);
   1027 
   1028   /* sign or space, pad, thousands separator with leading zeros */
   1029   check_sprintf (" 1,899347461279296875000000000000000000000E+07", "%' 030RE", x);
   1030   check_sprintf (" 000001,899347461279296875E+07", "%' 030RE", y);
   1031   check_sprintf (" 0000000000000000001,89935E+07", "%' 030RG", x);
   1032   check_sprintf (" 000000018.993.474,61279296875", "%' 030.19RG", x);
   1033   check_sprintf (" 00000000000018.993.474,612793", "%' 030RF", x);
   1034 
   1035 #define T1 "000"
   1036 #define T2 ".000"
   1037 #define S1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1 T1
   1038 #define S2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 T2 ","
   1039 
   1040   mpfr_set_ui (x, 48, MPFR_RNDN);
   1041   mpfr_exp10 (x, x, MPFR_RNDN);
   1042   check_sprintf ("1" S1, "%.0Rf", x);
   1043   check_sprintf ("1" S2, "%'#.0Rf", x);
   1044   check_sprintf ("1" S2 "0000", "%'.4Rf", x);
   1045   mpfr_mul_ui (x, x, 10, MPFR_RNDN);
   1046   check_sprintf ("10" S1, "%.0Rf", x);
   1047   check_sprintf ("10" S2, "%'#.0Rf", x);
   1048   check_sprintf ("10" S2 "0000", "%'.4Rf", x);
   1049   mpfr_mul_ui (x, x, 10, MPFR_RNDN);
   1050   check_sprintf ("100" S1, "%.0Rf", x);
   1051   check_sprintf ("100" S2, "%'#.0Rf", x);
   1052   check_sprintf ("100" S2 "0000", "%'.4Rf", x);
   1053 
   1054   mpfr_clear (x);
   1055   mpfr_clear (y);
   1056 
   1057   setlocale (LC_ALL, "C");
   1058 }
   1059 
   1060 #endif  /* ... && MPFR_LCONV_DPTS */
   1061 
   1062 /* check concordance between mpfr_asprintf result with a regular mpfr float
   1063    and with a regular double float */
   1064 static void
   1065 random_double (void)
   1066 {
   1067   mpfr_t x; /* random regular mpfr float */
   1068   double y; /* regular double float (equal to x) */
   1069 
   1070   char flag[] =
   1071     {
   1072       '-',
   1073       '+',
   1074       ' ',
   1075       '#',
   1076       '0', /* no ambiguity: first zeros are flag zero */
   1077       '\'' /* SUS extension */
   1078     };
   1079   /* no 'a': mpfr and glibc do not have the same semantic */
   1080   char specifier[] =
   1081     {
   1082       'e',
   1083       'f',
   1084       'g',
   1085       'E',
   1086       'f', /* SUSv2 doesn't accept %F, but %F and %f are the same for
   1087               regular numbers */
   1088       'G',
   1089     };
   1090   int spec; /* random index in specifier[] */
   1091   int prec; /* random value for precision field */
   1092 
   1093   /* in the format string for mpfr_t variable, the maximum length is
   1094      reached by something like "%-+ #0'.*Rf", that is 12 characters. */
   1095 #define FMT_MPFR_SIZE 12
   1096   char fmt_mpfr[FMT_MPFR_SIZE];
   1097   char *ptr_mpfr;
   1098 
   1099   /* in the format string for double variable, the maximum length is
   1100      reached by something like "%-+ #0'.*f", that is 11 characters. */
   1101 #define FMT_SIZE 11
   1102   char fmt[FMT_SIZE];
   1103   char *ptr;
   1104 
   1105   int xi;
   1106   char *xs;
   1107   int yi;
   1108   char *ys;
   1109 
   1110   int i, j, jmax;
   1111 
   1112   mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
   1113 
   1114   for (i = 0; i < 1000; ++i)
   1115     {
   1116       /* 1. random double */
   1117       do
   1118         {
   1119           y = DBL_RAND ();
   1120         }
   1121       while (ABS(y) < DBL_MIN);
   1122 
   1123       if (RAND_BOOL ())
   1124         y = -y;
   1125 
   1126       mpfr_set_d (x, y, MPFR_RNDN);
   1127       if (y != mpfr_get_d (x, MPFR_RNDN))
   1128         /* conversion error: skip this one */
   1129         continue;
   1130 
   1131       /* 2. build random format strings fmt_mpfr and fmt */
   1132       ptr_mpfr = fmt_mpfr;
   1133       ptr = fmt;
   1134       *ptr_mpfr++ = *ptr++ = '%';
   1135       /* random specifier 'e', 'f', 'g', 'E', 'F', or 'G' */
   1136       spec = (int) (randlimb() % 6);
   1137       /* random flags, but no ' flag with %e or with non-glibc */
   1138 #if __MPFR_GLIBC(1,0)
   1139       jmax = (spec == 0 || spec == 3) ? 5 : 6;
   1140 #else
   1141       jmax = 5;
   1142 #endif
   1143       for (j = 0; j < jmax; j++)
   1144         {
   1145           if (randlimb() % 3 == 0)
   1146             *ptr_mpfr++ = *ptr++ = flag[j];
   1147         }
   1148       *ptr_mpfr++ = *ptr++ = '.';
   1149       *ptr_mpfr++ = *ptr++ = '*';
   1150       *ptr_mpfr++ = 'R';
   1151       *ptr_mpfr++ = *ptr++ = specifier[spec];
   1152       *ptr_mpfr = *ptr = '\0';
   1153       MPFR_ASSERTN (ptr - fmt < FMT_SIZE);
   1154       MPFR_ASSERTN (ptr_mpfr - fmt_mpfr < FMT_MPFR_SIZE);
   1155 
   1156       /* advantage small precision */
   1157       prec = RAND_BOOL () ? 10 : prec_max_printf;
   1158       prec = (int) (randlimb () % prec);
   1159 
   1160       /* 3. calls and checks */
   1161       /* the double float case is handled by the libc asprintf through
   1162          gmp_asprintf */
   1163       xi = mpfr_asprintf (&xs, fmt_mpfr, prec, x);
   1164       yi = mpfr_asprintf (&ys, fmt, prec, y);
   1165 
   1166       /* test if XS and YS differ, beware that ISO C99 doesn't specify
   1167          the sign of a zero exponent (the C99 rationale says: "The sign
   1168          of a zero exponent in %e format is unspecified.  The committee
   1169          knows of different implementations and choose not to require
   1170          implementations to document their behavior in this case
   1171          (by making this be implementation defined behaviour).  Most
   1172          implementations use a "+" sign, e.g., 1.2e+00; but there is at
   1173          least one implementation that uses the sign of the unlimited
   1174          precision result, e.g., the 0.987 would be 9.87e-01, so could
   1175          end up as 1e-00 after rounding to one digit of precision."),
   1176          while mpfr always uses '+' */
   1177       if (xi != yi
   1178           || ((strcmp (xs, ys) != 0)
   1179               && (spec == 1 || spec == 4
   1180                   || ((strstr (xs, "e+00") == NULL
   1181                        || strstr (ys, "e-00") == NULL)
   1182                       && (strstr (xs, "E+00") == NULL
   1183                           || strstr (ys, "E-00") == NULL)))))
   1184         {
   1185           mpfr_printf ("Error in mpfr_asprintf(\"%s\", %d, %Re)\n",
   1186                        fmt_mpfr, prec, x);
   1187           printf ("expected: %s\n", ys);
   1188           printf ("     got: %s\n", xs);
   1189           printf ("xi=%d yi=%d spec=%d\n", xi, yi, spec);
   1190 
   1191           exit (1);
   1192         }
   1193 
   1194       mpfr_free_str (xs);
   1195       mpfr_free_str (ys);
   1196     }
   1197 
   1198   mpfr_clear (x);
   1199 }
   1200 
   1201 static void
   1202 bug20080610 (void)
   1203 {
   1204   /* bug on icc found on June 10, 2008 */
   1205   /* this is not a bug but a different implementation choice: ISO C99 doesn't
   1206      specify the sign of a zero exponent (see note in random_double above). */
   1207   mpfr_t x;
   1208   double y;
   1209   int xi;
   1210   char *xs;
   1211   int yi;
   1212   char *ys;
   1213 
   1214   mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
   1215 
   1216   y = -9.95645044213728791504536275169812142849e-01;
   1217   mpfr_set_d (x, y, MPFR_RNDN);
   1218 
   1219   xi = mpfr_asprintf (&xs, "%- #0.*Re", 1, x);
   1220   yi = mpfr_asprintf (&ys, "%- #0.*e", 1, y);
   1221 
   1222   if (xi != yi || strcmp (xs, ys) != 0)
   1223     {
   1224       printf ("Error in bug20080610\n");
   1225       printf ("expected: %s\n", ys);
   1226       printf ("     got: %s\n", xs);
   1227       printf ("xi=%d yi=%d\n", xi, yi);
   1228 
   1229       exit (1);
   1230     }
   1231 
   1232   mpfr_free_str (xs);
   1233   mpfr_free_str (ys);
   1234   mpfr_clear (x);
   1235 }
   1236 
   1237 static void
   1238 bug20081214 (void)
   1239 {
   1240  /* problem with glibc 2.3.6, December 14, 2008:
   1241     the system asprintf outputs "-1.0" instead of "-1.". */
   1242   mpfr_t x;
   1243   double y;
   1244   int xi;
   1245   char *xs;
   1246   int yi;
   1247   char *ys;
   1248 
   1249   mpfr_init2 (x, MPFR_LDBL_MANT_DIG);
   1250 
   1251   y = -9.90597761233942053494e-01;
   1252   mpfr_set_d (x, y, MPFR_RNDN);
   1253 
   1254   xi = mpfr_asprintf (&xs, "%- #0.*RG", 1, x);
   1255   yi = mpfr_asprintf (&ys, "%- #0.*G", 1, y);
   1256 
   1257   if (xi != yi || strcmp (xs, ys) != 0)
   1258     {
   1259       mpfr_printf ("Error in bug20081214\n"
   1260                    "mpfr_asprintf(\"%- #0.*Re\", 1, %Re)\n", x);
   1261       printf ("expected: %s\n", ys);
   1262       printf ("     got: %s\n", xs);
   1263       printf ("xi=%d yi=%d\n", xi, yi);
   1264 
   1265       exit (1);
   1266     }
   1267 
   1268   mpfr_free_str (xs);
   1269   mpfr_free_str (ys);
   1270   mpfr_clear (x);
   1271 }
   1272 
   1273 static void
   1274 bug20111102 (void)
   1275 {
   1276   mpfr_t t;
   1277   char s[100];
   1278 
   1279   mpfr_init2 (t, 84);
   1280   mpfr_set_str (t, "999.99999999999999999999", 10, MPFR_RNDN);
   1281   mpfr_sprintf (s, "%.20RNg", t);
   1282   if (strcmp (s, "1000") != 0)
   1283     {
   1284       printf ("Error in bug20111102, expected 1000, got %s\n", s);
   1285       exit (1);
   1286     }
   1287   mpfr_clear (t);
   1288 }
   1289 
   1290 /* In particular, the following test makes sure that the rounding
   1291  * for %Ra and %Rb is not done on the MPFR number itself (as it
   1292  * would overflow). Note: it has been reported on comp.std.c that
   1293  * some C libraries behave differently on %a, but this is a bug.
   1294  */
   1295 static void
   1296 check_emax_aux (mpfr_exp_t e)
   1297 {
   1298   mpfr_t x;
   1299   char *s1, s2[256];
   1300   int i;
   1301   mpfr_exp_t emax;
   1302 
   1303   MPFR_ASSERTN (e <= LONG_MAX);
   1304   emax = mpfr_get_emax ();
   1305   set_emax (e);
   1306 
   1307   mpfr_init2 (x, 16);
   1308 
   1309   mpfr_set_inf (x, 1);
   1310   mpfr_nextbelow (x);
   1311 
   1312   i = mpfr_asprintf (&s1, "%Ra %.2Ra", x, x);
   1313   MPFR_ASSERTN (i > 0);
   1314 
   1315   mpfr_snprintf (s2, 256, "0x7.fff8p+%ld 0x8.00p+%ld", e-3, e-3);
   1316 
   1317   if (strcmp (s1, s2) != 0)
   1318     {
   1319       printf ("Error in check_emax_aux for emax = ");
   1320       if (e > LONG_MAX)
   1321         printf ("(>LONG_MAX)\n");
   1322       else
   1323         printf ("%ld\n", (long) e);
   1324       printf ("Expected '%s'\n", s2);
   1325       printf ("Got      '%s'\n", s1);
   1326       exit (1);
   1327     }
   1328 
   1329   mpfr_free_str (s1);
   1330 
   1331   i = mpfr_asprintf (&s1, "%Rb %.2Rb", x, x);
   1332   MPFR_ASSERTN (i > 0);
   1333 
   1334   mpfr_snprintf (s2, 256, "1.111111111111111p+%ld 1.00p+%ld", e-1, e);
   1335 
   1336   if (strcmp (s1, s2) != 0)
   1337     {
   1338       printf ("Error in check_emax_aux for emax = ");
   1339       if (e > LONG_MAX)
   1340         printf ("(>LONG_MAX)\n");
   1341       else
   1342         printf ("%ld\n", (long) e);
   1343       printf ("Expected %s\n", s2);
   1344       printf ("Got      %s\n", s1);
   1345       exit (1);
   1346     }
   1347 
   1348   mpfr_free_str (s1);
   1349 
   1350   mpfr_clear (x);
   1351   set_emax (emax);
   1352 }
   1353 
   1354 static void
   1355 check_emax (void)
   1356 {
   1357   check_emax_aux (15);
   1358   check_emax_aux (MPFR_EMAX_MAX);
   1359 }
   1360 
   1361 static void
   1362 check_emin_aux (mpfr_exp_t e)
   1363 {
   1364   mpfr_t x;
   1365   char *s1, s2[256];
   1366   int i;
   1367   mpfr_exp_t emin;
   1368   mpz_t ee;
   1369 
   1370   MPFR_ASSERTN (e >= LONG_MIN);
   1371   emin = mpfr_get_emin ();
   1372   set_emin (e);
   1373 
   1374   mpfr_init2 (x, 16);
   1375   mpz_init (ee);
   1376 
   1377   mpfr_setmin (x, e);
   1378   mpz_set_si (ee, e);
   1379   mpz_sub_ui (ee, ee, 1);
   1380 
   1381   i = mpfr_asprintf (&s1, "%Ra", x);
   1382   MPFR_ASSERTN (i > 0);
   1383 
   1384   gmp_snprintf (s2, 256, "0x1p%Zd", ee);
   1385 
   1386   if (strcmp (s1, s2) != 0)
   1387     {
   1388       printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
   1389       printf ("Expected %s\n", s2);
   1390       printf ("Got      %s\n", s1);
   1391       exit (1);
   1392     }
   1393 
   1394   mpfr_free_str (s1);
   1395 
   1396   i = mpfr_asprintf (&s1, "%Rb", x);
   1397   MPFR_ASSERTN (i > 0);
   1398 
   1399   gmp_snprintf (s2, 256, "1p%Zd", ee);
   1400 
   1401   if (strcmp (s1, s2) != 0)
   1402     {
   1403       printf ("Error in check_emin_aux for emin = %ld\n", (long) e);
   1404       printf ("Expected %s\n", s2);
   1405       printf ("Got      %s\n", s1);
   1406       exit (1);
   1407     }
   1408 
   1409   mpfr_free_str (s1);
   1410 
   1411   mpfr_clear (x);
   1412   mpz_clear (ee);
   1413   set_emin (emin);
   1414 }
   1415 
   1416 static void
   1417 check_emin (void)
   1418 {
   1419   check_emin_aux (-15);
   1420   check_emin_aux (mpfr_get_emin ());
   1421   check_emin_aux (MPFR_EMIN_MIN);
   1422 }
   1423 
   1424 static void
   1425 test20161214 (void)
   1426 {
   1427   mpfr_t x;
   1428   char buf[32];
   1429   const char s[] = "0x0.fffffffffffff8p+1024";
   1430   int r;
   1431 
   1432   mpfr_init2 (x, 64);
   1433   mpfr_set_str (x, s, 16, MPFR_RNDN);
   1434   r = mpfr_snprintf (buf, 32, "%.*RDf", -2, x);
   1435   MPFR_ASSERTN(r == 316);
   1436   r = mpfr_snprintf (buf, 32, "%.*RDf", INT_MIN + 1, x);
   1437   MPFR_ASSERTN(r == 316);
   1438   r = mpfr_snprintf (buf, 32, "%.*RDf", INT_MIN, x);
   1439   MPFR_ASSERTN(r == 316);
   1440   mpfr_clear (x);
   1441 }
   1442 
   1443 /* http://gforge.inria.fr/tracker/index.php?func=detail&aid=21056 */
   1444 static void
   1445 bug21056 (void)
   1446 {
   1447   mpfr_t x;
   1448   const char s[] = "0x0.fffffffffffff8p+1024";
   1449   int ndigits, r;
   1450 
   1451   mpfr_init2 (x, 64);
   1452 
   1453   mpfr_set_str (x, s, 16, MPFR_RNDN);
   1454 
   1455   ndigits = 1000;
   1456   r = mpfr_snprintf (0, 0, "%.*RDf", ndigits, x);
   1457   /* the return value should be ndigits + 310 */
   1458   MPFR_ASSERTN(r == ndigits + 310);
   1459 
   1460   ndigits = INT_MAX - 310;
   1461   r = mpfr_snprintf (0, 0, "%.*RDf", ndigits, x);
   1462   MPFR_ASSERTN(r == INT_MAX);
   1463 
   1464   ndigits = INT_MAX - 10;
   1465   r = mpfr_snprintf (0, 0, "%.*RDa", ndigits, x);
   1466   MPFR_ASSERTN(r == INT_MAX);
   1467 
   1468   ndigits = INT_MAX - 7;
   1469   r = mpfr_snprintf (0, 0, "%.*RDe", ndigits, x);
   1470   MPFR_ASSERTN(r == INT_MAX);
   1471 
   1472   ndigits = 1000;
   1473   r = mpfr_snprintf (0, 0, "%.*RDg", ndigits, x);
   1474   /* since trailing zeros are removed with %g, we get less digits */
   1475   MPFR_ASSERTN(r == 309);
   1476 
   1477   ndigits = INT_MAX;
   1478   r = mpfr_snprintf (0, 0, "%.*RDg", ndigits, x);
   1479   /* since trailing zeros are removed with %g, we get less digits */
   1480   MPFR_ASSERTN(r == 309);
   1481 
   1482   ndigits = INT_MAX - 1;
   1483   r = mpfr_snprintf (0, 0, "%#.*RDg", ndigits, x);
   1484   MPFR_ASSERTN(r == ndigits + 1);
   1485 
   1486   mpfr_clear (x);
   1487 }
   1488 
   1489 /* Fails for i = 5, i.e. t[i] = (size_t) UINT_MAX + 1,
   1490    with r11427 on 64-bit machines (4-byte int, 8-byte size_t).
   1491    On such machines, t[5] converted to int typically gives 0.
   1492    Note: the assumed behavior corresponds to the snprintf behavior
   1493    in ISO C, but this conflicts with POSIX:
   1494      https://sourceware.org/bugzilla/show_bug.cgi?id=14771#c2
   1495      https://austingroupbugs.net/view.php?id=761
   1496      https://austingroupbugs.net/view.php?id=1219
   1497      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87096
   1498    Fixed in r11429.
   1499 */
   1500 static void
   1501 snprintf_size (void)
   1502 {
   1503   mpfr_t x;
   1504   char buf[12];
   1505   const char s[] = "17.00000000";
   1506   size_t t[] = { 11, 12, 64, INT_MAX, (size_t) INT_MAX + 1,
   1507                  (size_t) UINT_MAX + 1, (size_t) UINT_MAX + 2,
   1508                  (size_t) -1 };
   1509   int i, r;
   1510 
   1511   mpfr_init2 (x, 64);
   1512   mpfr_set_ui (x, 17, MPFR_RNDN);
   1513 
   1514   for (i = 0; i < sizeof (t) / sizeof (*t); i++)
   1515     {
   1516       memset (buf, 0, sizeof (buf));
   1517       /* r = snprintf (buf, t[i], "%.8f", 17.0); */
   1518       r = mpfr_snprintf (buf, t[i], "%.8Rf", x);
   1519       if (r != 11 || (t[i] > 11 && strcmp (buf, s) != 0))
   1520         {
   1521           printf ("Error in snprintf_size for i = %d:\n", i);
   1522           printf ("expected r = 11, \"%s\"\n", s);
   1523           printf ("got      r = %d, \"%s\"\n", r, buf);
   1524           exit (1);
   1525         }
   1526     }
   1527 
   1528   mpfr_clear (x);
   1529 }
   1530 
   1531 /* With r11516, n2 gets a random value for i = 0 only!
   1532    valgrind detects a problem for "nchar = buf.curr - buf.start;"
   1533    in the spec.spec == 'n' case. Indeed, there is no buffer when
   1534    size is 0. */
   1535 static void
   1536 percent_n (void)
   1537 {
   1538   int err = 0, i, j;
   1539 
   1540   for (i = 0; i < 24; i++)
   1541     for (j = 0; j < 3; j++)
   1542       {
   1543         volatile int n1, n2;
   1544         char buffer[64];
   1545 
   1546         memset (buffer, 0, 64);
   1547         n2 = -17;
   1548         n1 = mpfr_snprintf (buffer, i % 8, "%d%n", 123, &n2);
   1549         if (n1 != 3 || n2 != 3)
   1550           {
   1551             printf ("Error 1 in percent_n: i = %d, n1 = %d, n2 = %d\n",
   1552                     i, n1, n2);
   1553             err = 1;
   1554           }
   1555       }
   1556 
   1557   if (err)
   1558     exit (1);
   1559 }
   1560 
   1561 struct clo
   1562 {
   1563   const char *fmt;
   1564   int width, r, e;
   1565 };
   1566 
   1567 static void
   1568 check_length_overflow (void)
   1569 {
   1570   mpfr_t x;
   1571   int i, r, e;
   1572   struct clo t[] = {
   1573     { "%Rg", 0, 1, 0 },
   1574     { "%*Rg", 1, 1, 0 },
   1575     { "%*Rg", -1, 1, 0 },
   1576     { "%5Rg", 0, 5, 0 },
   1577     { "%*Rg", 5, 5, 0 },
   1578     { "%*Rg", -5, 5, 0 },
   1579 #if INT_MAX == 2147483647
   1580     { "%2147483647Rg", 0, 2147483647, 0 },
   1581     { "%2147483647Rg ", 0, -1, 1 },
   1582     { "%2147483648Rg", 0, -1, 1 },
   1583     { "%18446744073709551616Rg", 0, -1, 1 },
   1584     { "%*Rg", 2147483647, 2147483647, 0 },
   1585     { "%*Rg", -2147483647, 2147483647, 0 },
   1586 # if INT_MIN < -INT_MAX
   1587     { "%*Rg", INT_MIN, -1, 1 },
   1588 # endif
   1589 #endif
   1590   };
   1591 
   1592   mpfr_init2 (x, MPFR_PREC_MIN);
   1593   mpfr_set_ui (x, 0, MPFR_RNDN);
   1594 
   1595   for (i = 0; i < numberof (t); i++)
   1596     {
   1597       errno = 0;
   1598       r = t[i].width == 0 ?
   1599         mpfr_snprintf (NULL, 0, t[i].fmt, x) :
   1600         mpfr_snprintf (NULL, 0, t[i].fmt, t[i].width, x);
   1601       e = errno;
   1602       if ((t[i].r < 0 ? r >= 0 : r != t[i].r)
   1603 #ifdef EOVERFLOW
   1604           || (t[i].e && e != EOVERFLOW)
   1605 #endif
   1606           )
   1607         {
   1608           printf ("Error in check_length_overflow for i=%d (%s %d)\n",
   1609                   i, t[i].fmt, t[i].width);
   1610           printf ("Expected r=%d, got r=%d\n", t[i].r, r);
   1611 #ifdef EOVERFLOW
   1612           if (t[i].e && e != EOVERFLOW)
   1613             printf ("Expected errno=EOVERFLOW=%d, got errno=%d\n",
   1614                     EOVERFLOW, e);
   1615 #endif
   1616           exit (1);
   1617         }
   1618     }
   1619 
   1620   mpfr_clear (x);
   1621 }
   1622 
   1623 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
   1624 
   1625 /* The following tests should be equivalent to those from test_locale()
   1626    in tprintf.c (remove the \n at the end of the test strings). */
   1627 
   1628 static void
   1629 test_locale (void)
   1630 {
   1631   const char * const tab_locale[] = {
   1632     "en_US",
   1633     "en_US.iso88591",
   1634     "en_US.iso885915",
   1635     "en_US.utf8"
   1636   };
   1637   int i;
   1638   mpfr_t x;
   1639   char v[] = "99999999999999999999999.5";
   1640 
   1641   for (i = 0; i < numberof(tab_locale); i++)
   1642     {
   1643       char *s;
   1644 
   1645       s = setlocale (LC_ALL, tab_locale[i]);
   1646 
   1647       if (s != NULL && MPFR_THOUSANDS_SEPARATOR == ',')
   1648         break;
   1649     }
   1650 
   1651   if (i == numberof(tab_locale))
   1652     {
   1653       if (getenv ("MPFR_CHECK_LOCALES") == NULL)
   1654         return;
   1655 
   1656       fprintf (stderr, "Cannot find a locale with ',' thousands separator.\n"
   1657                "Please install one of the en_US based locales.\n");
   1658       exit (1);
   1659     }
   1660 
   1661   mpfr_init2 (x, 113);
   1662   mpfr_set_ui (x, 10000, MPFR_RNDN);
   1663 
   1664   check_sprintf ("(1) 10000=10,000 ", "(1) 10000=%'Rg ", x);
   1665   check_sprintf ("(2) 10000=10,000.000000 ", "(2) 10000=%'Rf ", x);
   1666 
   1667   mpfr_set_ui (x, 1000, MPFR_RNDN);
   1668   check_sprintf ("(3) 1000=1,000.000000 ", "(3) 1000=%'Rf ", x);
   1669 
   1670   for (i = 1; i <= sizeof (v) - 3; i++)
   1671     {
   1672       char buf[64];
   1673       int j;
   1674 
   1675       strcpy (buf, "(4) 10^i=1");
   1676       for (j = i; j > 0; j--)
   1677         strcat (buf, (j % 3 == 0) ? ",0" : "0");
   1678       strcat (buf, " ");
   1679       mpfr_set_str (x, v + sizeof (v) - 3 - i, 10, MPFR_RNDN);
   1680       check_sprintf (buf, "(4) 10^i=%'.0Rf ", x);
   1681     }
   1682 
   1683 #define N0 20
   1684 
   1685   for (i = 1; i <= N0; i++)
   1686     {
   1687       char s[N0+4], buf[64];
   1688       int j;
   1689 
   1690       s[0] = '1';
   1691       for (j = 1; j <= i; j++)
   1692         s[j] = '0';
   1693       s[i+1] = '\0';
   1694 
   1695       strcpy (buf, "(5) 10^i=1");
   1696       for (j = i; j > 0; j--)
   1697         strcat (buf, (j % 3 == 0) ? ",0" : "0");
   1698       strcat (buf, " ");
   1699 
   1700       mpfr_set_str (x, s, 10, MPFR_RNDN);
   1701 
   1702       check_sprintf (buf, "(5) 10^i=%'.0RNf ", x);
   1703       check_sprintf (buf, "(5) 10^i=%'.0RZf ", x);
   1704       check_sprintf (buf, "(5) 10^i=%'.0RUf ", x);
   1705       check_sprintf (buf, "(5) 10^i=%'.0RDf ", x);
   1706       check_sprintf (buf, "(5) 10^i=%'.0RYf ", x);
   1707 
   1708       strcat (s + (i + 1), ".5");
   1709       check_sprintf (buf, "(5) 10^i=%'.0Rf ", x);
   1710     }
   1711 
   1712   mpfr_set_str (x, "1000", 10, MPFR_RNDN);
   1713   check_sprintf ("00000001e+03", "%'012.3Rg", x);
   1714   check_sprintf ("00000001,000", "%'012.4Rg", x);
   1715   check_sprintf ("000000001,000", "%'013.4Rg", x);
   1716 
   1717 #ifdef PRINTF_GROUPFLAG
   1718   check_vsprintf ("+01,234,567  :", "%0+ -'13.10Pd:", (mpfr_prec_t) 1234567);
   1719 #endif
   1720 
   1721   mpfr_clear (x);
   1722 }
   1723 
   1724 #else
   1725 
   1726 static void
   1727 test_locale (void)
   1728 {
   1729   if (getenv ("MPFR_CHECK_LOCALES") != NULL)
   1730     {
   1731       fprintf (stderr, "Cannot test locales.\n");
   1732       exit (1);
   1733     }
   1734 }
   1735 
   1736 #endif
   1737 
   1738 int
   1739 main (int argc, char **argv)
   1740 {
   1741   int k;
   1742 
   1743   tests_start_mpfr ();
   1744 
   1745 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
   1746   /* currently, we just check with 'C' locale */
   1747   setlocale (LC_ALL, "C");
   1748 #endif
   1749 
   1750   bug20111102 ();
   1751 
   1752   for (k = 0; k < 40; k++)
   1753     {
   1754       native_types ();
   1755       hexadecimal ();
   1756       binary ();
   1757       decimal ();
   1758 
   1759 #if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
   1760       locale_da_DK ();
   1761 #else
   1762       if (getenv ("MPFR_CHECK_LOCALES") != NULL)
   1763         {
   1764           fprintf (stderr, "Cannot test locales.\n");
   1765           exit (1);
   1766         }
   1767 #endif
   1768     }
   1769 
   1770   check_emax ();
   1771   check_emin ();
   1772   test20161214 ();
   1773   bug21056 ();
   1774   snprintf_size ();
   1775   percent_n ();
   1776   mixed ();
   1777   check_length_overflow ();
   1778   test_locale ();
   1779 
   1780   if (getenv ("MPFR_CHECK_LIBC_PRINTF"))
   1781     {
   1782       /* check against libc */
   1783       random_double ();
   1784       bug20081214 ();
   1785       bug20080610 ();
   1786     }
   1787 
   1788   tests_end_mpfr ();
   1789   return 0;
   1790 }
   1791 
   1792 #else  /* HAVE_STDARG */
   1793 
   1794 int
   1795 main (void)
   1796 {
   1797   /* We have nothing to test. */
   1798   return 77;
   1799 }
   1800 
   1801 #endif  /* HAVE_STDARG */
   1802