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