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