Home | History | Annotate | Download | only in unit
      1 #include <limits>
      2 
      3 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
      4 #  include <iomanip>
      5 #  include <string>
      6 #  include <sstream>
      7 #  include <cstdio>
      8 /*
      9 #  include <iostream>
     10 #  include <ieee754.h>
     11 */
     12 
     13 #  include "complete_digits.h"
     14 #  include "cppunit/cppunit_proxy.h"
     15 
     16 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     17 using namespace std;
     18 #  endif
     19 
     20 //
     21 // TestCase class
     22 //
     23 class NumPutGetTest : public CPPUNIT_NS::TestCase
     24 {
     25   CPPUNIT_TEST_SUITE(NumPutGetTest);
     26 #  if defined (__BORLANDC__)
     27   /* Ignore FPU exceptions, set FPU precision to 64 bits */
     28   unsigned int _float_control_word = _control87(0, 0);
     29   _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);
     30 #  endif
     31   CPPUNIT_TEST(num_put_float);
     32   CPPUNIT_TEST(num_put_integer);
     33   CPPUNIT_TEST(num_get_float);
     34   CPPUNIT_TEST(num_get_integer);
     35   CPPUNIT_TEST(inhex);
     36   CPPUNIT_TEST(pointer);
     37   CPPUNIT_TEST(fix_float_long);
     38   CPPUNIT_TEST(custom_numpunct);
     39 #  if defined (__BORLANDC__)
     40   /* Reset floating point control word */
     41   _clear87();
     42   _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);
     43 #  endif
     44   CPPUNIT_TEST_SUITE_END();
     45 
     46 private:
     47   void num_put_float();
     48   void num_put_integer();
     49   void num_get_float();
     50   void num_get_integer();
     51   void inhex();
     52   void pointer();
     53   void fix_float_long();
     54   void custom_numpunct();
     55 
     56   static bool check_float(float val, float ref)
     57   {
     58     float epsilon = numeric_limits<float>::epsilon();
     59     return val <= ref + epsilon && val >= ref - epsilon;
     60   }
     61 
     62   static bool check_double(double val, double ref)
     63   {
     64     double epsilon = numeric_limits<double>::epsilon();
     65     return val <= ref + epsilon && val >= ref - epsilon;
     66   }
     67 
     68   static string reset_stream(ostringstream &ostr)
     69   {
     70     string tmp = ostr.str();
     71     ostr.str("");
     72     return tmp;
     73   }
     74 
     75 #if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES)
     76   template <class F>
     77   void check_get_float( F v )
     78   {
     79     F in_val_d = v;
     80     typedef numeric_limits<F> limits;
     81     {
     82       stringstream str;
     83 
     84       str << "1E+" << limits::max_exponent10;
     85 
     86       str >> in_val_d;
     87       CPPUNIT_ASSERT(!str.fail());
     88       CPPUNIT_ASSERT(str.eof());
     89       CPPUNIT_CHECK( in_val_d == in_val_d );
     90       CPPUNIT_CHECK( in_val_d != limits::infinity() );
     91     }
     92     {
     93       stringstream str;
     94 
     95       str << "-1E+" << limits::max_exponent10;
     96 
     97       str >> in_val_d;
     98       CPPUNIT_ASSERT(!str.fail());
     99       CPPUNIT_ASSERT(str.eof());
    100       CPPUNIT_CHECK( in_val_d == in_val_d );
    101       CPPUNIT_CHECK( in_val_d != -limits::infinity() );
    102     }
    103     {
    104       stringstream str;
    105 
    106       str << "1E" << limits::min_exponent10;
    107 
    108       str >> in_val_d;
    109       CPPUNIT_ASSERT(!str.fail());
    110       CPPUNIT_ASSERT(str.eof());
    111       CPPUNIT_CHECK( in_val_d == in_val_d );
    112       CPPUNIT_CHECK( in_val_d != F(0.0) );
    113     }
    114     {
    115       stringstream str;
    116 
    117       str << "1E+" << (limits::max_exponent10 + 1);
    118 
    119       str >> in_val_d;
    120       CPPUNIT_ASSERT(!str.fail());
    121       CPPUNIT_ASSERT(str.eof());
    122       CPPUNIT_CHECK( in_val_d == in_val_d );
    123       CPPUNIT_CHECK( in_val_d == limits::infinity() );
    124     }
    125     {
    126       stringstream str;
    127 
    128       str << "-1E+" << (limits::max_exponent10 + 1);
    129 
    130       str >> in_val_d;
    131       CPPUNIT_ASSERT(!str.fail());
    132       CPPUNIT_ASSERT(str.eof());
    133       CPPUNIT_CHECK( in_val_d == in_val_d );
    134       CPPUNIT_CHECK( in_val_d == -limits::infinity() );
    135     }
    136     {
    137       stringstream str;
    138 
    139       str << "1E" << (limits::min_exponent10 - 1);
    140 
    141       str >> in_val_d;
    142       CPPUNIT_ASSERT(!str.fail());
    143       CPPUNIT_ASSERT(str.eof());
    144       CPPUNIT_CHECK( in_val_d == in_val_d );
    145       CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= limits::min() );
    146     }
    147 #if !defined (__MINGW32__)
    148     {
    149       stringstream str;
    150 
    151       str << limits::max();
    152 
    153       CPPUNIT_ASSERT(!str.fail());
    154       CPPUNIT_CHECK( str.str() != "inf" && str.str() != "Inf" );
    155       CPPUNIT_CHECK( str.str() != "-inf" && str.str() != "-Inf" );
    156       CPPUNIT_CHECK( str.str() != "nan" && str.str() != "NaN" );
    157       CPPUNIT_CHECK( str.str() != "-nan" && str.str() != "-NaN" );
    158       //CPPUNIT_MESSAGE( str.str().c_str() );
    159 
    160       //str.str("");
    161       //str << limits::max_exponent10;
    162       //CPPUNIT_MESSAGE( str.str().c_str() );
    163 
    164       str >> in_val_d;
    165 
    166       CPPUNIT_ASSERT(!str.fail());
    167       CPPUNIT_ASSERT(str.eof());
    168       CPPUNIT_CHECK( in_val_d == in_val_d );
    169       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    170     }
    171     {
    172       stringstream str;
    173 
    174       str << fixed << limits::max();
    175 
    176       CPPUNIT_ASSERT(!str.fail());
    177       CPPUNIT_CHECK( str.str() != "inf" && str.str() != "Inf" );
    178       CPPUNIT_CHECK( str.str() != "-inf" && str.str() != "-Inf" );
    179       CPPUNIT_CHECK( str.str() != "nan" && str.str() != "NaN" );
    180       CPPUNIT_CHECK( str.str() != "-nan" && str.str() != "-NaN" );
    181       //CPPUNIT_MESSAGE( str.str().c_str() );
    182 
    183       //str.str("");
    184       //str << limits::max_exponent10;
    185       //CPPUNIT_MESSAGE( str.str().c_str() );
    186 
    187       str >> in_val_d;
    188 
    189       CPPUNIT_ASSERT(!str.fail());
    190       CPPUNIT_ASSERT(str.eof());
    191       CPPUNIT_CHECK( in_val_d == in_val_d );
    192       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    193     }
    194     {
    195       stringstream str;
    196 
    197       str << scientific << setprecision(50) << limits::max();
    198 
    199       CPPUNIT_ASSERT(!str.fail());
    200       CPPUNIT_CHECK( str.str() != "inf" && str.str() != "Inf" );
    201       CPPUNIT_CHECK( str.str() != "-inf" && str.str() != "-Inf" );
    202       CPPUNIT_CHECK( str.str() != "nan" && str.str() != "NaN" );
    203       CPPUNIT_CHECK( str.str() != "-nan" && str.str() != "-NaN" );
    204       //CPPUNIT_MESSAGE( str.str().c_str() );
    205 
    206       //str.str("");
    207       //str << limits::max_exponent10;
    208       //CPPUNIT_MESSAGE( str.str().c_str() );
    209 
    210       str >> in_val_d;
    211 
    212       CPPUNIT_ASSERT(!str.fail());
    213       CPPUNIT_ASSERT(str.eof());
    214       CPPUNIT_CHECK( in_val_d == in_val_d );
    215       CPPUNIT_CHECK( in_val_d != limits::infinity() );
    216     }
    217 #endif
    218     {
    219       stringstream str;
    220 
    221       str << limits::infinity();
    222 
    223       CPPUNIT_ASSERT( !str.fail() );
    224       CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "inf" || str.str() == "Inf" );
    225     }
    226     {
    227       stringstream str;
    228 
    229       str << -limits::infinity();
    230 
    231       CPPUNIT_ASSERT( !str.fail() );
    232       CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "-inf" || str.str() == "-Inf" );
    233     }
    234     {
    235       stringstream str;
    236 
    237       str << limits::quiet_NaN();
    238 
    239       CPPUNIT_ASSERT( !str.fail() );
    240       CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "nan" || str.str() == "NaN" );
    241     }
    242     {
    243       stringstream str;
    244 
    245       str << -limits::quiet_NaN();
    246 
    247       CPPUNIT_ASSERT( !str.fail() );
    248       CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "-nan" || str.str() == "NaN" );
    249     }
    250     {
    251       stringstream str;
    252 
    253       str << "0." << string(limits::max_exponent10, '0') << "1e" << (limits::max_exponent10 + 1);
    254       CPPUNIT_ASSERT( !str.fail() );
    255 
    256       str >> in_val_d;
    257       CPPUNIT_ASSERT( !str.fail() );
    258       CPPUNIT_ASSERT( str.eof() );
    259       CPPUNIT_CHECK( in_val_d == 1 );
    260     }
    261     {
    262       stringstream str;
    263 
    264       str << "1" << string(-(limits::min_exponent10 - 1), '0') << "e" << (limits::min_exponent10 - 1);
    265       CPPUNIT_ASSERT( !str.fail() );
    266 
    267       str >> in_val_d;
    268       CPPUNIT_ASSERT( !str.fail() );
    269       CPPUNIT_ASSERT( str.eof() );
    270       CPPUNIT_CHECK( in_val_d == 1 );
    271     }
    272 #  if defined (_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x530)
    273     // The following tests are showing that simply changing stream
    274     // precision lead to different result. Do not seems to be a real
    275     // problem, simply rounding approximation but additional study should
    276     // be done after 5.2 release.
    277     {
    278       stringstream str;
    279       str << setprecision(limits::digits10 + 2) << limits::max();
    280 
    281       CPPUNIT_MESSAGE(str.str().c_str());
    282       CPPUNIT_ASSERT( !str.fail() );
    283 
    284       F val;
    285       str >> val;
    286 
    287       CPPUNIT_ASSERT( !str.fail() );
    288       CPPUNIT_ASSERT( limits::infinity() > val );
    289     }
    290     {
    291       stringstream str;
    292       str << setprecision(limits::digits10 + 1) << limits::max();
    293 
    294       CPPUNIT_MESSAGE(str.str().c_str());
    295       CPPUNIT_ASSERT( !str.fail() );
    296 
    297       F val;
    298       str >> val;
    299 
    300       CPPUNIT_ASSERT( !str.fail() );
    301       CPPUNIT_ASSERT( limits::infinity() > val );
    302     }
    303 #  endif
    304   }
    305 #else
    306 #  define __check_get_float( F ) \
    307   void check_get_float( F v ) \
    308   { \
    309     F in_val_d = v; \
    310     { \
    311       stringstream str; \
    312  \
    313       str << "1E+" << numeric_limits<F>::max_exponent10; \
    314  \
    315       str >> in_val_d; \
    316       CPPUNIT_ASSERT(!str.fail()); \
    317       CPPUNIT_ASSERT(str.eof()); \
    318       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    319       CPPUNIT_CHECK( in_val_d != numeric_limits<F>::infinity() ); \
    320     } \
    321     { \
    322       stringstream str; \
    323  \
    324       str << "-1E+" << numeric_limits<F>::max_exponent10; \
    325  \
    326       str >> in_val_d; \
    327       CPPUNIT_ASSERT(!str.fail()); \
    328       CPPUNIT_ASSERT(str.eof()); \
    329       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    330       CPPUNIT_CHECK( in_val_d != -numeric_limits<F>::infinity() ); \
    331     } \
    332     { \
    333       stringstream str; \
    334  \
    335       str << "1E" << numeric_limits<F>::min_exponent10; \
    336  \
    337       str >> in_val_d; \
    338       CPPUNIT_ASSERT(!str.fail()); \
    339       CPPUNIT_ASSERT(str.eof()); \
    340       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    341       CPPUNIT_CHECK( in_val_d != F(0.0) ); \
    342     } \
    343     { \
    344       stringstream str; \
    345  \
    346       str << "1E+" << (numeric_limits<F>::max_exponent10 + 1); \
    347  \
    348       str >> in_val_d; \
    349       CPPUNIT_ASSERT(!str.fail()); \
    350       CPPUNIT_ASSERT(str.eof()); \
    351       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    352       CPPUNIT_CHECK( in_val_d == numeric_limits<F>::infinity() ); \
    353     } \
    354     { \
    355       stringstream str; \
    356  \
    357       str << "-1E+" << (numeric_limits<F>::max_exponent10 + 1); \
    358  \
    359       str >> in_val_d; \
    360       CPPUNIT_ASSERT(!str.fail()); \
    361       CPPUNIT_ASSERT(str.eof()); \
    362       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    363       CPPUNIT_CHECK( in_val_d == -numeric_limits<F>::infinity() ); \
    364     } \
    365     { \
    366       stringstream str; \
    367  \
    368       str << "1E" << (numeric_limits<F>::min_exponent10 - 1); \
    369  \
    370       str >> in_val_d; \
    371       CPPUNIT_ASSERT(!str.fail()); \
    372       CPPUNIT_ASSERT(str.eof()); \
    373       CPPUNIT_CHECK( in_val_d == in_val_d ); \
    374       CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= numeric_limits<F>::min() ); \
    375     } \
    376   }
    377 
    378   __check_get_float( float )
    379   __check_get_float( double )
    380 #  if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    381   __check_get_float( long double )
    382 #  endif
    383 #  undef __check_get_float
    384 #endif // _STLP_NO_MEMBER_TEMPLATES
    385 };
    386 
    387 CPPUNIT_TEST_SUITE_REGISTRATION(NumPutGetTest);
    388 
    389 #if defined (_MSC_VER)
    390 #  pragma warning (disable : 4056)
    391 #  pragma warning (disable : 4756)
    392 #endif
    393 
    394 //
    395 // tests implementation
    396 //
    397 void NumPutGetTest::num_put_float()
    398 {
    399   {
    400     string output, digits;
    401 
    402     {
    403       ostringstream ostr;
    404       ostr << 1.23457e+17f;
    405       CPPUNIT_ASSERT(ostr.good());
    406       output = reset_stream(ostr);
    407       digits = "17";
    408       complete_digits(digits);
    409       CPPUNIT_CHECK(output == string("1.23457e+") + digits );
    410     }
    411 
    412     {
    413       ostringstream ostr;
    414       ostr << setprecision(200) << 1.23457e+17f;
    415       CPPUNIT_ASSERT(ostr.good());
    416       output = reset_stream(ostr);
    417       CPPUNIT_CHECK( output.size() < 200 );
    418     }
    419 
    420     {
    421       ostringstream ostr;
    422       ostr << setprecision(200) << numeric_limits<float>::min();
    423       CPPUNIT_ASSERT(ostr.good());
    424       output = reset_stream(ostr);
    425       CPPUNIT_CHECK( output.size() < 200 );
    426     }
    427 
    428     {
    429       ostringstream ostr;
    430       ostr << fixed << 1.23457e+17f;
    431       CPPUNIT_ASSERT(ostr.good());
    432       output = reset_stream(ostr);
    433       CPPUNIT_CHECK(output.size() == 25);
    434       CPPUNIT_CHECK(output.substr(0, 5) == "12345");
    435       CPPUNIT_CHECK(output.substr(18) == ".000000");
    436     }
    437 
    438     {
    439       ostringstream ostr;
    440       ostr << fixed << showpos << 1.23457e+17f;
    441       CPPUNIT_ASSERT(ostr.good());
    442       output = reset_stream(ostr);
    443       CPPUNIT_CHECK(output.size() == 26);
    444       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    445       CPPUNIT_CHECK(output.substr(19) == ".000000");
    446     }
    447 
    448     {
    449       ostringstream ostr;
    450       ostr << fixed << showpos << setprecision(100) << 1.23457e+17f;
    451       CPPUNIT_ASSERT(ostr.good());
    452       output = reset_stream(ostr);
    453       CPPUNIT_CHECK(output.size() == 120);
    454       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    455       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    456     }
    457 
    458     {
    459       ostringstream ostr;
    460       ostr << scientific << setprecision(8) <<  0.12345678; // float doesn't have enough precision, 0.12345678f ended up 0.1234567836..
    461       CPPUNIT_ASSERT(ostr.good());
    462       output = reset_stream(ostr);
    463       digits = "1";
    464       complete_digits(digits);
    465       CPPUNIT_CHECK(output == string("1.23456780e-") + digits );
    466     }
    467 
    468     {
    469       ostringstream ostr;
    470       ostr << fixed << setprecision(8) << setw(30) << setfill('0') << 0.12345678f;
    471       CPPUNIT_ASSERT(ostr.good());
    472       output = reset_stream(ostr);
    473       CPPUNIT_CHECK(output == "000000000000000000000.12345678");
    474     }
    475 
    476     {
    477       ostringstream ostr;
    478       ostr << fixed << showpos << setprecision(8) << setw(30) << setfill('0') << 0.12345678f;
    479       CPPUNIT_ASSERT(ostr.good());
    480       output = reset_stream(ostr);
    481       CPPUNIT_CHECK(output == "0000000000000000000+0.12345678");
    482     }
    483 
    484     {
    485       ostringstream ostr;
    486       ostr << fixed << showpos << setprecision(8) << setw(30) << left << setfill('0') << 0.12345678f;
    487       CPPUNIT_ASSERT(ostr.good());
    488       output = reset_stream(ostr);
    489       CPPUNIT_CHECK(output == "+0.123456780000000000000000000");
    490     }
    491 
    492     {
    493       ostringstream ostr;
    494       ostr << fixed << showpos << setprecision(8) << setw(30) << internal << setfill('0') << 0.12345678f;
    495       CPPUNIT_ASSERT(ostr.good());
    496       output = reset_stream(ostr);
    497       CPPUNIT_CHECK(output == "+00000000000000000000.12345678");
    498     }
    499 
    500     {
    501       ostringstream ostr;
    502       ostr << fixed << showpos << setprecision(100) << 1.234567e+17;
    503       CPPUNIT_ASSERT(ostr.good());
    504       output = reset_stream(ostr);
    505       CPPUNIT_CHECK(output.size() == 120);
    506       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    507       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    508     }
    509 
    510 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    511     {
    512       ostringstream ostr;
    513       ostr << fixed << showpos << setprecision(100) << 1.234567e+17l;
    514       CPPUNIT_ASSERT(ostr.good());
    515       output = reset_stream(ostr);
    516       CPPUNIT_CHECK(output.size() == 120);
    517       CPPUNIT_CHECK(output.substr(0, 6) == "+12345");
    518       CPPUNIT_CHECK(output.substr(19) == ".0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    519     }
    520 #endif
    521 
    522     {
    523       ostringstream ostr;
    524       ostr << scientific << setprecision(50) << 0.0;
    525       CPPUNIT_ASSERT(ostr.good());
    526       output = reset_stream(ostr);
    527       CPPUNIT_CHECK( output == "0.00000000000000000000000000000000000000000000000000e+00" );
    528     }
    529     {
    530       ostringstream ostr;
    531       ostr << fixed << setprecision(100) << numeric_limits<float>::max();
    532       CPPUNIT_ASSERT(ostr.good());
    533       output = reset_stream(ostr);
    534       //CPPUNIT_MESSAGE( output.c_str() );
    535     }
    536 
    537     {
    538       ostringstream ostr;
    539       ostr << setprecision(100) << numeric_limits<double>::max();
    540       CPPUNIT_ASSERT(ostr.good());
    541       output = reset_stream(ostr);
    542       //CPPUNIT_MESSAGE( output.c_str() );
    543     }
    544 
    545 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    546     {
    547       ostringstream ostr;
    548       ostr << setprecision(100) << numeric_limits<long double>::max();
    549       CPPUNIT_ASSERT(ostr.good());
    550       output = reset_stream(ostr);
    551       //CPPUNIT_MESSAGE( output.c_str() );
    552     }
    553 #endif
    554 
    555     //{
    556     //  ostringstream ostr;
    557     //  ostr << setprecision(-numeric_limits<float>::min_exponent10 + numeric_limits<float>::digits10 + 9) << numeric_limits<float>::min();
    558     //  CPPUNIT_ASSERT(ostr.good());
    559     //  output = reset_stream(ostr);
    560     //  //CPPUNIT_MESSAGE( output.c_str() );
    561     //}
    562 
    563     //{
    564     //  ostringstream ostr;
    565     //  ostr << setprecision(-numeric_limits<double>::min_exponent10 + numeric_limits<double>::digits10) << numeric_limits<double>::min();
    566     //  CPPUNIT_ASSERT(ostr.good());
    567     //  output = reset_stream(ostr);
    568     //  //CPPUNIT_MESSAGE( output.c_str() );
    569     //}
    570 
    571 //#if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    572 //    {
    573 //      ostringstream ostr;
    574 //      ostr << setprecision(-numeric_limits<long double>::min_exponent10 + numeric_limits<long double>::digits10) << numeric_limits<long double>::min();
    575 //      CPPUNIT_ASSERT(ostr.good());
    576 //      output = reset_stream(ostr);
    577 //      CPPUNIT_MESSAGE( output.c_str() );
    578 //    }
    579 //#endif
    580   }
    581 
    582   {
    583     ostringstream str;
    584 
    585     str.setf(ios::fixed, ios::floatfield);
    586     str << 1.0e+5;
    587     // cerr << str.str() << endl;
    588     CPPUNIT_CHECK( str.str() == "100000.000000" );
    589 
    590     reset_stream(str);
    591     str.precision(0);
    592     str << 1.0e+5;
    593     CPPUNIT_CHECK( str.str() == "100000" );
    594 
    595     reset_stream(str);
    596     str.precision(4);
    597     str << 1.0e+5;
    598     CPPUNIT_CHECK( str.str() == "100000.0000" );
    599 
    600     reset_stream(str);
    601     str.precision(0);
    602     str << 1.0e+83;
    603     CPPUNIT_CHECK( str.str().size() == 84 );
    604     //printf("\nC result: %.0f\n", 1.0e+83);
    605     //CPPUNIT_MESSAGE( str.str().c_str() );
    606     //CPPUNIT_CHECK( str.str() == "100000000000000000000000000000000000000000000000000000000000000000000000000000000000" );
    607 
    608     // cerr.setf(ios::fixed, ios::floatfield);
    609     // cerr << DBL_MAX << endl;
    610     // cerr << 1.0e+37 << endl;
    611   }
    612 }
    613 
    614 #define CHECK_COMPLETE(type, val, base, showbase, showpos, casing, width, adjust, expected) \
    615 { \
    616   type tmp = val; \
    617   ostringstream ostr; \
    618   ostr << base << showbase << showpos << casing << setw(width) << adjust << tmp; \
    619   CPPUNIT_CHECK( ostr.str() == expected ); \
    620 }
    621 
    622 #define CHECK(type, val, base, expected) \
    623   CHECK_COMPLETE(type, val, base, noshowbase, noshowpos, nouppercase, 0, right, expected)
    624 
    625 void NumPutGetTest::num_put_integer()
    626 {
    627   //octal outputs
    628   {
    629     CHECK(short, 0, oct, "0")
    630     CHECK(short, 1, oct, "1")
    631     CHECK(short, 12345, oct, "30071")
    632     if (sizeof(short) == 2) {
    633       CHECK(short, -1, oct, "177777")
    634       CHECK(short, -12345, oct, "147707")
    635     }
    636 
    637     CHECK(unsigned short, 0, oct, "0")
    638     CHECK(unsigned short, 12345, oct, "30071")
    639 
    640     CHECK(int, 0, oct, "0")
    641     CHECK(int, 12345678, oct, "57060516")
    642     if (sizeof(int) == 4) {
    643       CHECK(int, -1, oct, "37777777777")
    644       CHECK(int, -12345678, oct, "37720717262")
    645     }
    646 
    647     CHECK(unsigned int, 0, oct, "0")
    648     CHECK(unsigned int, 12345678, oct, "57060516")
    649 
    650     CHECK(long, 0, oct, "0")
    651     CHECK(long, 12345678, oct, "57060516")
    652     if (sizeof(long) == 4) {
    653       CHECK(long, -1, oct, "37777777777")
    654       CHECK(long, -12345678, oct, "37720717262")
    655     }
    656 
    657     CHECK(unsigned long, 0, oct, "0")
    658     CHECK(unsigned long, 12345678, oct, "57060516")
    659 
    660 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    661     CHECK(_STLP_LONG_LONG, 0, oct, "0")
    662     CHECK(_STLP_LONG_LONG, 12345678, oct, "57060516")
    663     if (sizeof(_STLP_LONG_LONG) == 8) {
    664       CHECK(_STLP_LONG_LONG, -1, oct, "1777777777777777777777")
    665       CHECK(_STLP_LONG_LONG, -12345678, oct, "1777777777777720717262")
    666     }
    667 
    668     CHECK(unsigned _STLP_LONG_LONG, 0, oct, "0")
    669     CHECK(unsigned _STLP_LONG_LONG, 12345678, oct, "57060516")
    670 #endif
    671 
    672     //Even with showbase, 0 value gives "0" (see printf documentation)
    673     CHECK_COMPLETE(short, 0, oct, showbase, noshowpos, nouppercase, 0, right, "0")
    674     CHECK_COMPLETE(short, 0, oct, showbase, showpos, nouppercase, 6, right, "     0")
    675 
    676     CHECK_COMPLETE(short, 1, oct, showbase, noshowpos, nouppercase, 6, right, "    01")
    677     CHECK_COMPLETE(short, 1, oct, showbase, noshowpos, nouppercase, 6, left, "01    ")
    678     CHECK_COMPLETE(short, 1, oct, showbase, showpos, nouppercase, 6, internal, "    01")
    679   }
    680 
    681   //decimal outputs
    682   {
    683     CHECK(short, 0, dec, "0")
    684     CHECK(short, -1, dec, "-1")
    685     CHECK(short, 12345, dec, "12345")
    686     CHECK(short, -12345, dec, "-12345")
    687 
    688     CHECK(unsigned short, 0, dec, "0")
    689     CHECK(unsigned short, 12345, dec, "12345")
    690 
    691     CHECK(int, 0, dec, "0")
    692     CHECK(int, -1, dec, "-1")
    693     CHECK(int, 12345678, dec, "12345678")
    694     CHECK(int, -12345678, dec, "-12345678")
    695 
    696     CHECK(unsigned int, 0, dec, "0")
    697     CHECK(unsigned int, 12345678, dec, "12345678")
    698 
    699     CHECK(long, 0, dec, "0")
    700     CHECK(long, -1, dec, "-1")
    701     CHECK(long, 12345678, dec, "12345678")
    702     CHECK(long, -12345678, dec, "-12345678")
    703 
    704     CHECK(unsigned long, 0, dec, "0")
    705     CHECK(unsigned long, 12345678, dec, "12345678")
    706 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    707     CHECK(_STLP_LONG_LONG, 0, dec, "0")
    708     CHECK(_STLP_LONG_LONG, -1, dec, "-1")
    709     CHECK(_STLP_LONG_LONG, 12345678, dec, "12345678")
    710     CHECK(_STLP_LONG_LONG, -12345678, dec, "-12345678")
    711 
    712     CHECK(unsigned _STLP_LONG_LONG, 0, dec, "0")
    713     CHECK(unsigned _STLP_LONG_LONG, 12345678, dec, "12345678")
    714 #endif
    715 
    716     CHECK_COMPLETE(short, 0, dec, showbase, showpos, nouppercase, 0, right, "+0")
    717     CHECK_COMPLETE(short, 0, dec, showbase, showpos, nouppercase, 6, right, "    +0")
    718     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, right, "    +1")
    719     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, left, "+1    ")
    720     CHECK_COMPLETE(short, 1, dec, showbase, showpos, nouppercase, 6, internal, "+    1")
    721   }
    722 
    723   //hexadecimal outputs
    724   {
    725     CHECK(short, 0, hex, "0")
    726     CHECK(short, 12345, hex, "3039")
    727     if (sizeof(short) == 2) {
    728       CHECK(short, -1, hex, "ffff")
    729       CHECK(short, -12345, hex, "cfc7")
    730     }
    731 
    732     CHECK(unsigned short, 0, hex, "0")
    733     CHECK(unsigned short, 12345, hex, "3039")
    734 
    735     CHECK(int, 0, hex, "0")
    736     CHECK(int, 12345678, hex, "bc614e")
    737     if (sizeof(int) == 4) {
    738       CHECK(int, -1, hex, "ffffffff")
    739       CHECK(int, -12345678, hex, "ff439eb2")
    740     }
    741 
    742     CHECK(unsigned int, 0, hex, "0")
    743     CHECK(unsigned int, 12345678, hex, "bc614e")
    744 
    745     CHECK(long, 0, hex, "0")
    746     CHECK(long, 12345678, hex, "bc614e")
    747     if (sizeof(long) == 4) {
    748       CHECK(long, -1, hex, "ffffffff")
    749       CHECK(long, -12345678, hex, "ff439eb2")
    750     }
    751 
    752     CHECK(unsigned long, 0, hex, "0")
    753     CHECK(unsigned long, 12345678, hex, "bc614e")
    754 #if defined (STLPORT) && defined (_STLP_LONG_LONG)
    755     CHECK(_STLP_LONG_LONG, 0, hex, "0")
    756     CHECK(_STLP_LONG_LONG, 12345678, hex, "bc614e")
    757     if (sizeof(_STLP_LONG_LONG) == 8) {
    758       CHECK(_STLP_LONG_LONG, -1, hex, "ffffffffffffffff")
    759       CHECK(_STLP_LONG_LONG, -12345678, hex, "ffffffffff439eb2")
    760     }
    761 
    762     CHECK(unsigned _STLP_LONG_LONG, 0, hex, "0")
    763     CHECK(unsigned _STLP_LONG_LONG, 12345678, hex, "bc614e")
    764 #endif
    765 
    766     //Even with showbase, 0 value gives "0" output (see printf documentation)
    767     CHECK_COMPLETE(short, 0, hex, showbase, showpos, nouppercase, 0, right, "0")
    768     CHECK_COMPLETE(short, 0, hex, showbase, noshowpos, nouppercase, 6, right, "     0")
    769     CHECK_COMPLETE(short, 0, hex, showbase, noshowpos, nouppercase, 6, internal, "     0")
    770 
    771     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, right, "   0x1")
    772     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, left, "0x1   ")
    773     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, nouppercase, 6, internal, "0x   1")
    774     CHECK_COMPLETE(short, 1, hex, showbase, noshowpos, uppercase, 6, left, "0X1   ")
    775     CHECK_COMPLETE(short, 1, hex, showbase, showpos, uppercase, 6, internal, "0X   1")
    776   }
    777 }
    778 
    779 void NumPutGetTest::num_get_float()
    780 {
    781   float in_val;
    782 
    783   istringstream istr;
    784 
    785   istr.str("1.2345");
    786   istr >> in_val;
    787   CPPUNIT_ASSERT(!istr.fail());
    788   CPPUNIT_ASSERT(istr.eof());
    789   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    790   istr.clear();
    791 
    792   istr.str("-1.2345");
    793   istr >> in_val;
    794   CPPUNIT_ASSERT(!istr.fail());
    795   CPPUNIT_ASSERT(istr.eof());
    796   CPPUNIT_ASSERT(check_float(in_val, -1.2345f));
    797   istr.clear();
    798 
    799   istr.str("+1.2345");
    800   istr >> in_val;
    801   CPPUNIT_ASSERT(!istr.fail());
    802   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    803   istr.clear();
    804 
    805   istr.str("000000000000001.234500000000");
    806   istr >> in_val;
    807   CPPUNIT_ASSERT(!istr.fail());
    808   CPPUNIT_ASSERT(istr.eof());
    809   CPPUNIT_ASSERT(check_float(in_val, 1.2345f));
    810   istr.clear();
    811 
    812   istr.str("1.2345e+04");
    813   istr >> in_val;
    814   CPPUNIT_ASSERT(!istr.fail());
    815   CPPUNIT_ASSERT(istr.eof());
    816   CPPUNIT_ASSERT(check_float(in_val, 12345.0f));
    817   istr.clear();
    818 
    819   CPPUNIT_MESSAGE( "float" );
    820   check_get_float( 0.0F );
    821   CPPUNIT_MESSAGE( "double" );
    822   check_get_float( 0.0 );
    823 #if (!defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)) && !defined(__ANDROID__)
    824   CPPUNIT_MESSAGE( "long double" );
    825   check_get_float( 0.0L );
    826 #endif
    827   {
    828     stringstream str;
    829 
    830     str << "1e" << numeric_limits<double>::max_exponent10;
    831     CPPUNIT_ASSERT(!str.fail());
    832 
    833     float val;
    834     str >> val;
    835     CPPUNIT_ASSERT(!str.fail());
    836     CPPUNIT_ASSERT(str.eof());
    837     CPPUNIT_ASSERT( numeric_limits<double>::max_exponent10 <= numeric_limits<float>::max_exponent10 ||
    838                     val == numeric_limits<float>::infinity() );
    839   }
    840   {
    841     stringstream str;
    842 
    843     str << "1e" << numeric_limits<double>::min_exponent10;
    844     CPPUNIT_ASSERT(!str.fail());
    845 
    846     float val;
    847     str >> val;
    848     CPPUNIT_ASSERT(!str.fail());
    849     CPPUNIT_ASSERT(str.eof());
    850     CPPUNIT_ASSERT( numeric_limits<double>::min_exponent10 >= numeric_limits<float>::min_exponent10 ||
    851                     val == 0.0f );
    852   }
    853 #if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE)
    854   {
    855     stringstream str;
    856 
    857     str << "1e" << numeric_limits<long double>::max_exponent10;
    858     CPPUNIT_ASSERT(!str.fail());
    859 
    860     double val;
    861     str >> val;
    862     CPPUNIT_ASSERT(!str.fail());
    863     CPPUNIT_ASSERT(str.eof());
    864     CPPUNIT_ASSERT( numeric_limits<long double>::max_exponent10 <= numeric_limits<double>::max_exponent10 ||
    865                     val == numeric_limits<double>::infinity() );
    866   }
    867   {
    868     stringstream str;
    869 
    870     str << "1e" << numeric_limits<long double>::min_exponent10;
    871     CPPUNIT_ASSERT(!str.fail());
    872 
    873     double val;
    874     str >> val;
    875     CPPUNIT_ASSERT(!str.fail());
    876     CPPUNIT_ASSERT(str.eof());
    877     CPPUNIT_ASSERT( numeric_limits<long double>::min_exponent10 >= numeric_limits<double>::min_exponent10 ||
    878                     val == 0.0 );
    879   }
    880 #if !defined(__ANDROID__) // "long double" in Android is still a distinct type but size is the same as "double"
    881   {
    882     const char* p = "2.718281828459045235360287471352662497757247093e0";
    883     std::stringstream s;
    884     s << p;
    885     long double x;
    886     s >> x;
    887     CPPUNIT_ASSERT( x > 2.70l && x < 2.72l );
    888   }
    889 #endif
    890 #endif
    891 }
    892 
    893 void NumPutGetTest::num_get_integer()
    894 {
    895   //octal input
    896   {
    897     istringstream istr;
    898     istr.str("30071");
    899     short val;
    900     istr >> oct >> val;
    901     CPPUNIT_ASSERT( !istr.fail() );
    902     CPPUNIT_ASSERT( istr.eof() );
    903     CPPUNIT_ASSERT( val == 12345 );
    904     istr.clear();
    905 
    906     if (sizeof(short) == 2) {
    907       istr.str("177777");
    908       istr >> oct >> val;
    909       CPPUNIT_ASSERT( !istr.fail() );
    910       CPPUNIT_ASSERT( istr.eof() );
    911       CPPUNIT_ASSERT( val == -1 );
    912       istr.clear();
    913     }
    914   }
    915 
    916   //decimal input
    917   {
    918     istringstream istr;
    919     istr.str("10000");
    920     short val = -1;
    921     istr >> val;
    922     CPPUNIT_ASSERT( !istr.fail() );
    923     CPPUNIT_ASSERT( istr.eof() );
    924     CPPUNIT_ASSERT( val == 10000 );
    925     istr.clear();
    926 
    927     istr.str("+10000");
    928     val = -1;
    929     istr >> val;
    930     CPPUNIT_ASSERT( !istr.fail() );
    931     CPPUNIT_ASSERT( istr.eof() );
    932     CPPUNIT_ASSERT( val == 10000 );
    933     istr.clear();
    934 
    935     if (sizeof(short) == 2) {
    936       val = -1;
    937       istr.str("10000000");
    938       istr >> val;
    939       CPPUNIT_ASSERT( istr.fail() );
    940       CPPUNIT_ASSERT( istr.eof() );
    941       CPPUNIT_ASSERT( val == -1 );
    942       istr.clear();
    943     }
    944 
    945     val = -1;
    946     istr.str("0x0");
    947     istr >> val;
    948     CPPUNIT_ASSERT( !istr.fail() );
    949     CPPUNIT_ASSERT( !istr.eof() );
    950     CPPUNIT_ASSERT( val == 0 );
    951     istr.clear();
    952 
    953     val = -1;
    954     istr.str("000001");
    955     istr >> val;
    956     CPPUNIT_ASSERT( !istr.fail() );
    957     CPPUNIT_ASSERT( istr.eof() );
    958     CPPUNIT_ASSERT( val == 1 );
    959     istr.clear();
    960   }
    961 
    962   //hexadecimal input
    963   {
    964     istringstream istr;
    965     istr.str("3039");
    966     short val = -1;
    967     istr >> hex >> val;
    968     CPPUNIT_ASSERT( !istr.fail() );
    969     CPPUNIT_ASSERT( istr.eof() );
    970     CPPUNIT_ASSERT( val == 12345 );
    971     istr.clear();
    972 
    973     istr.str("x3039");
    974     val = -1;
    975     istr >> hex >> val;
    976     CPPUNIT_ASSERT( istr.fail() );
    977     CPPUNIT_ASSERT( !istr.eof() );
    978     CPPUNIT_ASSERT( val == -1 );
    979     istr.clear();
    980 
    981     istr.str("03039");
    982     val = -1;
    983     istr >> hex >> val;
    984     CPPUNIT_ASSERT( !istr.fail() );
    985     CPPUNIT_ASSERT( istr.eof() );
    986     CPPUNIT_ASSERT( val == 12345 );
    987     istr.clear();
    988 
    989     istr.str("0x3039");
    990     istr >> hex >> val;
    991     CPPUNIT_ASSERT( !istr.fail() );
    992     CPPUNIT_ASSERT( istr.eof() );
    993     CPPUNIT_ASSERT( val == 12345 );
    994     istr.clear();
    995 
    996     if (sizeof(short) == 2) {
    997       val = -1;
    998       istr.str("cfc7");
    999       istr >> hex >> val;
   1000       CPPUNIT_ASSERT( !istr.fail() );
   1001       CPPUNIT_ASSERT( istr.eof() );
   1002       CPPUNIT_ASSERT( val == -12345 );
   1003       istr.clear();
   1004     }
   1005   }
   1006 }
   1007 
   1008 void NumPutGetTest::inhex()
   1009 {
   1010   {
   1011     ostringstream s;
   1012     s << hex << 0;
   1013     CPPUNIT_CHECK( s.str() == "0" );
   1014   }
   1015   {
   1016     ostringstream s;
   1017     s << hex << 0xff;
   1018     CPPUNIT_CHECK( s.str() == "ff" );
   1019   }
   1020   {
   1021     ostringstream s;
   1022     s << hex << setw( 4 ) << 0xff;
   1023     CPPUNIT_CHECK( s.str() == "  ff" );
   1024   }
   1025   {
   1026     ostringstream s;
   1027     s << hex << setw( 4 ) << 0;
   1028     CPPUNIT_CHECK( s.str() == "   0" );
   1029   }
   1030   {
   1031     ostringstream s;
   1032     s << hex << showbase << 0;
   1033     CPPUNIT_CHECK( s.str() == "0" );
   1034   }
   1035   {
   1036     ostringstream s;
   1037     s << hex << showbase << 0xff;
   1038     CPPUNIT_CHECK( s.str() == "0xff" );
   1039   }
   1040   {
   1041     ostringstream s;
   1042     s << hex << showbase << setw( 4 ) << 0xff;
   1043     CPPUNIT_CHECK( s.str() == "0xff" );
   1044   }
   1045   { // special case for regression (partially duplicate CHECK_COMPLETE above):
   1046     ostringstream s;
   1047     s.setf( ios_base::internal, ios_base::adjustfield );
   1048     s << hex << showbase << setw(8+2) << 0;
   1049     CPPUNIT_CHECK( s.str() == "         0" );
   1050   }
   1051 }
   1052 
   1053 void NumPutGetTest::pointer()
   1054 {
   1055   // Problem with printing pointer to null
   1056 
   1057   /*
   1058    * Really C's formatting not help here, due to:
   1059    *
   1060    * p  The argument shall be a pointer to void. The value of
   1061    *    the pointer is converted to a sequence of printable characters,
   1062    *    in an implementation-defined manner.
   1063    */
   1064   {
   1065     /*
   1066     char buf[128];
   1067     void *p = (void *)0xff00;
   1068     sprintf( buf, "%p", p );
   1069     // cerr << buf << endl;
   1070     // Hmmm, I see 0xff00 on box with 32-bits address; pointer like 'unsigned hex'?
   1071     if ( sizeof( p ) == 2 ) {
   1072       CPPUNIT_ASSERT( strcmp( buf, "0xff00" ) == 0 );
   1073     } else if ( sizeof( p ) == 4 ) {
   1074       CPPUNIT_ASSERT( strcmp( buf, "0x0000ff00" ) == 0 );
   1075     } else if ( sizeof( p ) == 8 ) {
   1076       CPPUNIT_ASSERT( strcmp( buf, "0x000000000000ff00" ) == 0 );
   1077     } else {
   1078       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1079     }
   1080     */
   1081   }
   1082   {
   1083     /*
   1084     char buf[128];
   1085     void *p = 0;
   1086     */
   1087     // sprintf( buf, "%p", p );
   1088     /* Cool. "%p" print '(nil)'; "%#x" print '0' */
   1089     // sprintf( buf, "%#x", (unsigned)p );
   1090     // cerr << buf << endl;
   1091   }
   1092   {
   1093     ostringstream s;
   1094     void *p = (void *)0xff00;
   1095     s << p;
   1096     CPPUNIT_ASSERT( s.good() );
   1097     if ( sizeof( p ) == 2 ) {
   1098       CPPUNIT_ASSERT( s.str() == "0xff00" );
   1099     } else if ( sizeof( p ) == 4 ) {
   1100       CPPUNIT_ASSERT( s.str() == "0x0000ff00" ); // this pass
   1101     } else if ( sizeof( p ) == 8 ) {
   1102       CPPUNIT_ASSERT( s.str() == "0x000000000000ff00" );
   1103     } else {
   1104       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1105     }
   1106   }
   1107   {
   1108     ostringstream s;
   1109     void *p = 0;
   1110     s << p;
   1111     CPPUNIT_ASSERT( s.good() );
   1112     if ( sizeof( p ) == 2 ) {
   1113       CPPUNIT_ASSERT( s.str() == "0x0000" );
   1114     } else if ( sizeof( p ) == 4 ) {
   1115       CPPUNIT_ASSERT( s.str() == "0x00000000" ); // but this will fail, if follow %p
   1116     } else if ( sizeof( p ) == 8 ) {
   1117       CPPUNIT_ASSERT( s.str() == "0x0000000000000000" );
   1118     } else {
   1119       CPPUNIT_CHECK( sizeof( p ) == 2 || sizeof( p ) == 4 || sizeof( p ) == 8 );
   1120     }
   1121   }
   1122 }
   1123 
   1124 void NumPutGetTest::fix_float_long()
   1125 {
   1126   ostringstream str;
   1127 
   1128   str.setf(ios::fixed, ios::floatfield);
   1129   str << 1.0e+5;
   1130   CPPUNIT_CHECK( str.str() == "100000.000000" );
   1131 
   1132   reset_stream(str);
   1133   str.precision(0);
   1134   str << 1.0e+5;
   1135   CPPUNIT_CHECK( str.str() == "100000" );
   1136 
   1137   reset_stream(str);
   1138   str.precision(4);
   1139   str << 1.0e+5;
   1140   CPPUNIT_CHECK( str.str() == "100000.0000" );
   1141 
   1142   reset_stream(str);
   1143   str.precision(0);
   1144   str << 1.0e+83;
   1145   {
   1146     istringstream istr( str.str() );
   1147     double f;
   1148     istr >> f;
   1149     CPPUNIT_CHECK( !istr.fail() );
   1150     if ( int(numeric_limits<double>::digits10) < 83 ) {
   1151       double delta = 1.0;
   1152       for ( int ee = 83 - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1153         delta *= 10.0;
   1154       }
   1155       // we may loss some digits here, but not more than mantissa:
   1156       CPPUNIT_CHECK( (f > (1.0e+83 - delta)) && (f < (1.0e+83 + delta)) );
   1157     } else {
   1158       CPPUNIT_CHECK( check_double(f, 1.0e+83) );
   1159     }
   1160   }
   1161 
   1162 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1163   reset_stream(str);
   1164   str.precision(0);
   1165   str << 1.0e+83l;
   1166   {
   1167     istringstream istr( str.str() );
   1168     long double f;
   1169     istr >> f;
   1170     CPPUNIT_CHECK( !istr.fail() );
   1171     if ( int(numeric_limits<long double>::digits10) < 83 ) {
   1172       long double delta = 1.0l;
   1173       for ( int ee = 83 - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1174         delta *= 10.0l;
   1175       }
   1176       // we may loss some digits here, but not more than mantissa:
   1177       cerr << "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" << endl;
   1178       cerr << str.str() << endl;
   1179       cerr << delta << endl;
   1180       cerr << f << endl;
   1181       CPPUNIT_CHECK( (f > (1.0e+83l - delta)) && (f < (1.0e+83l + delta)) );
   1182     } else {
   1183       CPPUNIT_CHECK( check_double(f, 1.0e+83l) );
   1184     }
   1185   }
   1186 #endif
   1187 
   1188   reset_stream(str);
   1189   str.precision(0);
   1190   str << numeric_limits<double>::max();
   1191   {
   1192     istringstream istr( str.str() );
   1193     double f;
   1194     istr >> f;
   1195     CPPUNIT_CHECK( !istr.fail() );
   1196     if ( int(numeric_limits<double>::digits10) < int(numeric_limits<double>::max_exponent10) ) {
   1197       double delta = 9.0;
   1198       for ( int ee = int(numeric_limits<double>::max_exponent10) - int(numeric_limits<double>::digits10); ee > 0; --ee ) {
   1199         delta *= 10.0;
   1200       }
   1201       // we may loss some digits here, but not more than mantissa:
   1202       CPPUNIT_CHECK( (f > (numeric_limits<double>::max() - delta)) );
   1203     }
   1204   }
   1205 
   1206 #if 0 // #ifndef _STLP_NO_LONG_DOUBLE
   1207   reset_stream(str);
   1208   str.precision(0);
   1209   str << numeric_limits<long double>::max();
   1210   {
   1211     istringstream istr( str.str() );
   1212     long double f;
   1213     istr >> f;
   1214     CPPUNIT_CHECK( !istr.fail() );
   1215     if ( int(numeric_limits<long double>::digits10) < int(numeric_limits<long double>::max_exponent10) ) {
   1216       long double delta = 1.0l;
   1217       for ( int ee = int(numeric_limits<long double>::max_exponent10) - int(numeric_limits<long double>::digits10); ee > 0; --ee ) {
   1218         delta *= 10.0l;
   1219       }
   1220       // we may loss some digits here, but not more than mantissa:
   1221       CPPUNIT_CHECK( (f > (numeric_limits<long double>::max() - delta)) );
   1222     }
   1223   }
   1224 #endif
   1225 }
   1226 
   1227 class CommaSepNumPunct : public numpunct<char> {
   1228   char do_thousands_sep() const { return ','; }
   1229   string do_grouping() const { return string("\1\2\3") + (char)CHAR_MAX; }
   1230 };
   1231 
   1232 #define CHECK2(val, expected) \
   1233   os.str(""); os << fixed << setprecision(3) << showpos << val; \
   1234   CPPUNIT_ASSERT( os.str() == expected )
   1235 
   1236 // Use unadulterated os2 when expecting inf
   1237 #define CHECKINF(val, expected, expected2) \
   1238   os2.str(""); os2 << fixed << setprecision(4) << showpos << val; \
   1239   CPPUNIT_ASSERT( os2.str() == expected || os2.str() == expected2 )
   1240 
   1241 void NumPutGetTest::custom_numpunct()
   1242 {
   1243     ostringstream os, os2;
   1244     locale loc(os.getloc(), new CommaSepNumPunct());
   1245     os.imbue(loc);
   1246 
   1247     CHECK2(1, "+1");
   1248     CHECK2(10, "+1,0");
   1249     CHECK2(100, "+10,0");
   1250     CHECK2(1000, "+1,00,0");
   1251 
   1252     CHECK2(1.234, "+1.234");
   1253     CHECK2(123.456, "+12,3.456");
   1254     CHECK2(1234.567, "+1,23,4.567");
   1255     CHECK2(12345.678, "+12,34,5.678");
   1256     CHECK2(123456.789, "+123,45,6.789");
   1257     CHECK2(1234567.891, "+1,234,56,7.891");
   1258     CHECK2(123456789.123, "+123,456,78,9.123");
   1259     //CHECK2(100000000000000000000000000000.0, "+100000000000000000000000,000,00,0.000");
   1260     CHECKINF(numeric_limits<double>::infinity(), "+inf", "+Inf");
   1261 
   1262     CHECK2(-1.234, "-1.234");
   1263     CHECK2(-123.456, "-12,3.456");
   1264     CHECK2(-1234.567, "-1,23,4.567");
   1265     CHECK2(-12345.678, "-12,34,5.678");
   1266     CHECK2(-123456.789, "-123,45,6.789");
   1267     CHECK2(-1234567.891, "-1,234,56,7.891");
   1268     CHECK2(-123456789.123, "-123,456,78,9.123");
   1269     //CHECK2(-100000000000000000000000000000.0, "-100000000000000000000000,000,00,0.000");
   1270     CHECKINF(-numeric_limits<double>::infinity(), "-inf", "-Inf");
   1271 }
   1272 
   1273 #endif
   1274