github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/cxx/t-ostream.cc (about)

     1  /* Test ostream formatted output.
     2  
     3  Copyright 2001, 2002 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <iostream>
    21  #include <cstdlib>
    22  
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  using namespace std;
    28  
    29  
    30  bool option_check_standard = false;
    31  
    32  
    33  #define CALL(expr)							\
    34    do {									\
    35      got.flags (data[i].flags);						\
    36      got.width (data[i].width);						\
    37      got.precision (data[i].precision);					\
    38      if (data[i].fill == '\0')						\
    39        got.fill (' ');							\
    40      else								\
    41        got.fill (data[i].fill);						\
    42  									\
    43      if (! (expr))							\
    44        {									\
    45  	cout << "\"got\" output error\n";				\
    46  	abort ();							\
    47        }									\
    48      if (got.width() != 0)						\
    49        {									\
    50  	cout << "\"got\" width not reset to 0\n";			\
    51  	abort ();							\
    52        }									\
    53  									\
    54    } while (0)
    55  
    56  
    57  #define DUMP()								\
    58    do {									\
    59      cout << "  want:  |" << data[i].want << "|\n";			\
    60      cout << "  got:   |" << got.str() << "|\n";				\
    61      cout << "  width: " << data[i].width << "\n";			\
    62      cout << "  prec:  " << got.precision() << "\n";			\
    63      cout << "  flags: " << hex << (unsigned long) got.flags() << "\n";	\
    64    } while (0)
    65  
    66  #define ABORT() \
    67    do {          \
    68      DUMP ();    \
    69      abort ();   \
    70    } while (0)
    71  
    72  void
    73  check_mpz (void)
    74  {
    75    static const struct {
    76      const char     *z;
    77      const char     *want;
    78      ios::fmtflags  flags;
    79      int            width;
    80      int            precision;
    81      char           fill;
    82  
    83    } data[] = {
    84  
    85      { "0", "0", ios::dec },
    86  
    87      { "0", "0", ios::oct },
    88      { "0", "0", ios::oct | ios::showbase },
    89  
    90      { "0", "0", ios::hex },
    91      { "0", "0x0", ios::hex | ios::showbase },
    92      { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
    93  
    94      { "1", "****1", ios::dec, 5, 0, '*' },
    95  
    96      { "-1", "   -1",  ios::dec | ios::right,    5 },
    97      { "-1", "-   1",  ios::dec | ios::internal, 5 },
    98      { "-1", "-1   ",  ios::dec | ios::left,     5 },
    99  
   100      { "1", "   0x1", ios::hex | ios::showbase | ios::right,    6 },
   101      { "1", "0x   1", ios::hex | ios::showbase | ios::internal, 6 },
   102      { "1", "0x1   ", ios::hex | ios::showbase | ios::left,     6 },
   103  
   104      { "1", "   +0x1", ios::hex | ios::showbase | ios::showpos | ios::right,
   105        7 },
   106      { "1", "+0x   1", ios::hex | ios::showbase | ios::showpos | ios::internal,
   107        7 },
   108      { "1", "+0x1   ", ios::hex | ios::showbase | ios::showpos | ios::left,
   109        7 },
   110  
   111      {  "123",    "7b", ios::hex },
   112      {  "123",    "7B", ios::hex | ios::uppercase },
   113      {  "123",  "0x7b", ios::hex | ios::showbase },
   114      {  "123",  "0X7B", ios::hex | ios::showbase | ios::uppercase },
   115      { "-123", "-0x7b", ios::hex | ios::showbase },
   116      { "-123", "-0X7B", ios::hex | ios::showbase | ios::uppercase },
   117  
   118      {  "123",   "173", ios::oct },
   119      {  "123",   "173", ios::oct | ios::uppercase },
   120      {  "123",  "0173", ios::oct | ios::showbase },
   121      {  "123",  "0173", ios::oct | ios::showbase | ios::uppercase },
   122      { "-123", "-0173", ios::oct | ios::showbase },
   123      { "-123", "-0173", ios::oct | ios::showbase | ios::uppercase },
   124  
   125    };
   126  
   127    size_t  i;
   128    mpz_t   z;
   129  
   130    mpz_init (z);
   131  
   132    for (i = 0; i < numberof (data); i++)
   133      {
   134        mpz_set_str_or_abort (z, data[i].z, 0);
   135  
   136        if (option_check_standard
   137  	  && mpz_fits_slong_p (z)
   138  
   139  	  // no negatives or showpos in hex or oct
   140  	  && (((data[i].flags & ios::basefield) == ios::hex
   141  	       || (data[i].flags & ios::basefield) == ios::oct)
   142  	      ? (mpz_sgn (z) >= 0
   143  		 && ! (data[i].flags & ios::showpos))
   144  	      : 1)
   145  	  )
   146  	{
   147  	  ostringstream  got;
   148  	  long  n = mpz_get_si (z);
   149  	  CALL (got << n);
   150  	  if (got.str().compare (data[i].want) != 0)
   151  	    {
   152  	      cout << "check_mpz data[" << i
   153  		   << "] doesn't match standard ostream output\n";
   154  	      cout << "  z:     " << data[i].z << "\n";
   155  	      cout << "  n:     " << n << "\n";
   156  	      DUMP ();
   157  	    }
   158  	}
   159  
   160        {
   161  	ostringstream  got;
   162  	CALL (got << z);
   163  	if (got.str().compare (data[i].want) != 0)
   164  	  {
   165  	    cout << "mpz operator<< wrong, data[" << i << "]\n";
   166  	    cout << "  z:     " << data[i].z << "\n";
   167  	    ABORT ();
   168  	  }
   169        }
   170      }
   171  
   172    mpz_clear (z);
   173  }
   174  
   175  void
   176  check_mpq (void)
   177  {
   178    static const struct {
   179      const char     *q;
   180      const char     *want;
   181      ios::fmtflags  flags;
   182      int            width;
   183      int            precision;
   184      char           fill;
   185  
   186    } data[] = {
   187  
   188      { "0", "0", ios::dec },
   189      { "0", "0", ios::hex },
   190      { "0", "0x0", ios::hex | ios::showbase },
   191      { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
   192  
   193      { "5/8", "5/8", ios::dec },
   194      { "5/8", "0X5/0X8", ios::hex | ios::showbase | ios::uppercase },
   195  
   196      // zero denominator with showbase
   197      { "0/0",   "       0/0", ios::oct | ios::showbase, 10 },
   198      { "0/0",   "       0/0", ios::dec | ios::showbase, 10 },
   199      { "0/0",   "   0x0/0x0", ios::hex | ios::showbase, 10 },
   200      { "123/0", "    0173/0", ios::oct | ios::showbase, 10 },
   201      { "123/0", "     123/0", ios::dec | ios::showbase, 10 },
   202      { "123/0", "  0x7b/0x0", ios::hex | ios::showbase, 10 },
   203      { "123/0", "  0X7B/0X0", ios::hex | ios::showbase | ios::uppercase, 10 },
   204      { "0/123", "    0/0173", ios::oct | ios::showbase, 10 },
   205      { "0/123", "     0/123", ios::dec | ios::showbase, 10 },
   206      { "0/123", "  0x0/0x7b", ios::hex | ios::showbase, 10 },
   207      { "0/123", "  0X0/0X7B", ios::hex | ios::showbase | ios::uppercase, 10 },
   208    };
   209  
   210    size_t  i;
   211    mpq_t   q;
   212  
   213    mpq_init (q);
   214  
   215  #define mpq_integer_p(q)  (mpz_cmp_ui (mpq_denref(q), 1L) == 0)
   216  
   217    for (i = 0; i < numberof (data); i++)
   218      {
   219        mpq_set_str_or_abort (q, data[i].q, 0);
   220        MPZ_CHECK_FORMAT (mpq_numref (q));
   221        MPZ_CHECK_FORMAT (mpq_denref (q));
   222  
   223        if (option_check_standard
   224  	  && mpz_fits_slong_p (mpq_numref(q))
   225  	  && mpq_integer_p (q))
   226  	{
   227  	  ostringstream  got;
   228  	  long  n = mpz_get_si (mpq_numref(q));
   229  	  CALL (got << n);
   230  	  if (got.str().compare (data[i].want) != 0)
   231  	    {
   232  	      cout << "check_mpq data[" << i
   233  		   << "] doesn't match standard ostream output\n";
   234  	      cout << "  q:     " << data[i].q << "\n";
   235  	      cout << "  n:     " << n << "\n";
   236  	      DUMP ();
   237  	    }
   238  	}
   239  
   240        {
   241  	ostringstream  got;
   242  	CALL (got << q);
   243  	if (got.str().compare (data[i].want) != 0)
   244  	  {
   245  	    cout << "mpq operator<< wrong, data[" << i << "]\n";
   246  	    cout << "  q:     " << data[i].q << "\n";
   247  	    ABORT ();
   248  	  }
   249        }
   250      }
   251  
   252    mpq_clear (q);
   253  }
   254  
   255  
   256  void
   257  check_mpf (void)
   258  {
   259    static const struct {
   260      const char     *f;
   261      const char     *want;
   262      ios::fmtflags  flags;
   263      int            width;
   264      int            precision;
   265      char           fill;
   266  
   267    } data[] = {
   268  
   269      { "0", "0",            ios::dec },
   270      { "0", "+0",           ios::dec | ios::showpos },
   271      { "0", "0.00000",      ios::dec | ios::showpoint },
   272      { "0", "0",            ios::dec | ios::fixed },
   273      { "0", "0.",           ios::dec | ios::fixed | ios::showpoint },
   274      { "0", "0.000000e+00", ios::dec | ios::scientific },
   275      { "0", "0.000000e+00", ios::dec | ios::scientific | ios::showpoint },
   276  
   277      { "0", "0",          ios::dec, 0, 4 },
   278      { "0", "0.000",      ios::dec | ios::showpoint, 0, 4 },
   279      { "0", "0.0000",     ios::dec | ios::fixed, 0, 4 },
   280      { "0", "0.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
   281      { "0", "0.0000e+00", ios::dec | ios::scientific, 0, 4 },
   282      { "0", "0.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
   283  
   284      { "1", "1",       ios::dec },
   285      { "1", "+1",      ios::dec | ios::showpos },
   286      { "1", "1.00000", ios::dec | ios::showpoint },
   287      { "1", "1",       ios::dec | ios::fixed },
   288      { "1", "1.",      ios::dec | ios::fixed | ios::showpoint },
   289      { "1", "1.000000e+00",   ios::dec | ios::scientific },
   290      { "1", "1.000000e+00",  ios::dec | ios::scientific | ios::showpoint },
   291  
   292      { "1", "1",          ios::dec,                   0, 4 },
   293      { "1", "1.000",      ios::dec | ios::showpoint,  0, 4 },
   294      { "1", "1.0000",     ios::dec | ios::fixed,      0, 4 },
   295      { "1", "1.0000",     ios::dec | ios::fixed | ios::showpoint, 0, 4 },
   296      { "1", "1.0000e+00", ios::dec | ios::scientific, 0, 4 },
   297      { "1", "1.0000e+00", ios::dec | ios::scientific | ios::showpoint, 0, 4 },
   298  
   299      { "-1", "-1",        ios::dec | ios::showpos },
   300  
   301      { "-1", "  -1",      ios::dec, 4 },
   302      { "-1", "-  1",      ios::dec | ios::internal, 4 },
   303      { "-1", "-1  ",      ios::dec | ios::left, 4 },
   304  
   305      { "-1", "  -0x1",    ios::hex | ios::showbase, 6 },
   306      { "-1", "-0x  1",    ios::hex | ios::showbase | ios::internal, 6 },
   307      { "-1", "-0x1  ",    ios::hex | ios::showbase | ios::left, 6 },
   308  
   309      {    "1", "*********1", ios::dec, 10, 4, '*' },
   310      { "1234", "******1234", ios::dec, 10, 4, '*' },
   311      { "1234", "*****1234.", ios::dec | ios::showpoint, 10, 4, '*' },
   312  
   313      { "12345", "1.23e+04", ios::dec, 0, 3 },
   314  
   315      { "12345", "12345.", ios::dec | ios::fixed | ios::showpoint },
   316  
   317      { "1.9999999",    "2",     ios::dec, 0, 1 },
   318      { "1.0009999999", "1.001", ios::dec, 0, 4 },
   319      { "1.0001",       "1",     ios::dec, 0, 4 },
   320      { "1.0004",       "1",     ios::dec, 0, 4 },
   321      { "1.000555",     "1.001", ios::dec, 0, 4 },
   322  
   323      { "1.0002",       "1.000", ios::dec | ios::fixed, 0, 3 },
   324      { "1.0008",       "1.001", ios::dec | ios::fixed, 0, 3 },
   325  
   326      { "0", "0", ios::hex },
   327      { "0", "0x0", ios::hex | ios::showbase },
   328      { "0", "0X0", ios::hex | ios::showbase | ios::uppercase },
   329      { "123",   "7b", ios::hex },
   330      { "123", "0x7b", ios::hex | ios::showbase },
   331      { "123", "0X7B", ios::hex | ios::showbase | ios::uppercase },
   332  
   333      { "0", "0.000@+00", ios::hex | ios::scientific, 0, 3 },
   334      { "256", "1.000@+02", ios::hex | ios::scientific, 0, 3 },
   335  
   336      { "123",   "7.b@+01", ios::hex | ios::scientific, 0, 1 },
   337      { "123",   "7.B@+01", ios::hex | ios::scientific | ios::uppercase, 0, 1 },
   338      { "123", "0x7.b@+01", ios::hex | ios::scientific | ios::showbase, 0, 1 },
   339      { "123", "0X7.B@+01",
   340        ios::hex | ios::scientific | ios::showbase | ios::uppercase, 0, 1 },
   341  
   342      { "1099511627776", "1.0@+10", ios::hex | ios::scientific, 0, 1 },
   343      { "1099511627776", "1.0@+10",
   344        ios::hex | ios::scientific | ios::uppercase, 0, 1 },
   345  
   346      { "0.0625", "1.00@-01", ios::hex | ios::scientific, 0, 2 },
   347  
   348      { "0", "0", ios::oct },
   349      { "123",  "173", ios::oct },
   350      { "123", "0173", ios::oct | ios::showbase },
   351  
   352      // octal showbase suppressed for 0
   353      { "0", "0", ios::oct | ios::showbase },
   354      { ".125",    "00.1",  ios::oct | ios::showbase, 0, 1 },
   355      { ".015625", "00.01", ios::oct | ios::showbase, 0, 2 },
   356      { ".125",    "00.1",  ios::fixed | ios::oct | ios::showbase, 0, 1 },
   357      { ".015625", "0.0",   ios::fixed | ios::oct | ios::showbase, 0, 1 },
   358      { ".015625", "00.01", ios::fixed | ios::oct | ios::showbase, 0, 2 },
   359  
   360      {  "0.125",  "1.000000e-01", ios::oct | ios::scientific },
   361      {  "0.125", "+1.000000e-01", ios::oct | ios::scientific | ios::showpos },
   362      { "-0.125", "-1.000000e-01", ios::oct | ios::scientific },
   363      { "-0.125", "-1.000000e-01", ios::oct | ios::scientific | ios::showpos },
   364  
   365      { "0", "0.000e+00", ios::oct | ios::scientific, 0, 3 },
   366      { "256",  "4.000e+02", ios::oct | ios::scientific, 0, 3 },
   367      { "256", "04.000e+02", ios::oct | ios::scientific | ios::showbase, 0, 3 },
   368      { "256",  "4.000E+02", ios::oct | ios::scientific | ios::uppercase, 0, 3 },
   369      { "256", "04.000E+02",
   370        ios::oct | ios::scientific | ios::showbase | ios::uppercase, 0, 3 },
   371  
   372      { "16777216",    "1.000000e+08", ios::oct | ios::scientific },
   373      { "16777216",    "1.000000E+08",
   374        ios::oct | ios::scientific | ios::uppercase },
   375      { "16777216",   "01.000000e+08",
   376        ios::oct | ios::scientific | ios::showbase },
   377      { "16777216",   "01.000000E+08",
   378        ios::oct | ios::scientific | ios::showbase | ios::uppercase },
   379      { "16777216",  "+01.000000e+08",
   380        ios::oct | ios::scientific | ios::showbase | ios::showpos },
   381      { "16777216",  "+01.000000E+08", ios::oct | ios::scientific
   382        | ios::showbase | ios::showpos | ios::uppercase },
   383      { "-16777216", "-01.000000e+08",
   384        ios::oct | ios::scientific | ios::showbase | ios::showpos },
   385      { "-16777216", "-01.000000E+08", ios::oct | ios::scientific
   386        | ios::showbase | ios::showpos | ios::uppercase },
   387  
   388    };
   389  
   390    size_t  i;
   391    mpf_t   f, f2;
   392    double  d;
   393  
   394    mpf_init (f);
   395    mpf_init (f2);
   396  
   397    for (i = 0; i < numberof (data); i++)
   398      {
   399        mpf_set_str_or_abort (f, data[i].f, 0);
   400  
   401        d = mpf_get_d (f);
   402        mpf_set_d (f2, d);
   403        if (option_check_standard && mpf_cmp (f, f2) == 0
   404  	  && ! (data[i].flags & (ios::hex | ios::oct | ios::showbase)))
   405  	{
   406  	  ostringstream  got;
   407  	  CALL (got << d);
   408  	  if (got.str().compare (data[i].want) != 0)
   409  	    {
   410  	      cout << "check_mpf data[" << i
   411  		   << "] doesn't match standard ostream output\n";
   412  	      cout << "  f:     " << data[i].f << "\n";
   413  	      cout << "  d:     " << d << "\n";
   414  	      DUMP ();
   415  	    }
   416  	}
   417  
   418        {
   419  	ostringstream  got;
   420  	CALL (got << f);
   421  	if (got.str().compare (data[i].want) != 0)
   422  	  {
   423  	    cout << "mpf operator<< wrong, data[" << i << "]\n";
   424  	    cout << "  f:     " << data[i].f << "\n";
   425  	    ABORT ();
   426  	  }
   427        }
   428      }
   429  
   430    mpf_clear (f);
   431    mpf_clear (f2);
   432  }
   433  
   434  
   435  
   436  int
   437  main (int argc, char *argv[])
   438  {
   439    if (argc > 1 && strcmp (argv[1], "-s") == 0)
   440      option_check_standard = true;
   441  
   442    tests_start ();
   443  
   444    check_mpz ();
   445    check_mpq ();
   446    check_mpf ();
   447  
   448    tests_end ();
   449    return 0;
   450  }