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