📄 num_put_get_test.cpp
字号:
#include <limits>#if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)# include <iomanip># include <string># include <sstream># include <cstdio>/*# include <iostream># include <ieee754.h>*/# include "complete_digits.h"# include "cppunit/cppunit_proxy.h"# if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)using namespace std;# endif//// TestCase class//class NumPutGetTest : public CPPUNIT_NS::TestCase{ CPPUNIT_TEST_SUITE(NumPutGetTest);# if defined (__BORLANDC__) /* Ignore FPU exceptions, set FPU precision to 64 bits */ unsigned int _float_control_word = _control87(0, 0); _control87(PC_64|MCW_EM|IC_AFFINE, MCW_PC|MCW_EM|MCW_IC);# endif CPPUNIT_TEST(num_put_float); CPPUNIT_TEST(num_put_integer); CPPUNIT_TEST(num_get_float); CPPUNIT_TEST(num_get_integer); CPPUNIT_TEST(inhex); CPPUNIT_TEST(pointer); CPPUNIT_TEST(fix_float_long); CPPUNIT_TEST(custom_numpunct);# if defined (__BORLANDC__) /* Reset floating point control word */ _clear87(); _control87(_float_control_word, MCW_PC|MCW_EM|MCW_IC);# endif CPPUNIT_TEST_SUITE_END();private: void num_put_float(); void num_put_integer(); void num_get_float(); void num_get_integer(); void inhex(); void pointer(); void fix_float_long(); void custom_numpunct(); static bool check_float(float val, float ref) { float epsilon = numeric_limits<float>::epsilon(); return val <= ref + epsilon && val >= ref - epsilon; } static bool check_double(double val, double ref) { double epsilon = numeric_limits<double>::epsilon(); return val <= ref + epsilon && val >= ref - epsilon; } static string reset_stream(ostringstream &ostr) { string tmp = ostr.str(); ostr.str(""); return tmp; }#if !defined (STLPORT) || !defined (_STLP_NO_MEMBER_TEMPLATES) template <class F> void check_get_float( F v ) { F in_val_d = v; typedef numeric_limits<F> limits; { stringstream str; str << "1E+" << limits::max_exponent10; str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != limits::infinity() ); } { stringstream str; str << "-1E+" << limits::max_exponent10; str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != -limits::infinity() ); } { stringstream str; str << "1E" << limits::min_exponent10; str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != F(0.0) ); } { stringstream str; str << "1E+" << (limits::max_exponent10 + 1); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d == limits::infinity() ); } { stringstream str; str << "-1E+" << (limits::max_exponent10 + 1); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d == -limits::infinity() ); } { stringstream str; str << "1E" << (limits::min_exponent10 - 1); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= limits::min() ); }#if !defined (__MINGW32__) { stringstream str; str << limits::max(); CPPUNIT_ASSERT(!str.fail()); CPPUNIT_CHECK( str.str() != "inf" ); CPPUNIT_CHECK( str.str() != "-inf" ); CPPUNIT_CHECK( str.str() != "nan" ); CPPUNIT_CHECK( str.str() != "-nan" ); //CPPUNIT_MESSAGE( str.str().c_str() ); //str.str(""); //str << limits::max_exponent10; //CPPUNIT_MESSAGE( str.str().c_str() ); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != limits::infinity() ); } { stringstream str; str << fixed << limits::max(); CPPUNIT_ASSERT(!str.fail()); CPPUNIT_CHECK( str.str() != "inf" ); CPPUNIT_CHECK( str.str() != "-inf" ); CPPUNIT_CHECK( str.str() != "nan" ); CPPUNIT_CHECK( str.str() != "-nan" ); //CPPUNIT_MESSAGE( str.str().c_str() ); //str.str(""); //str << limits::max_exponent10; //CPPUNIT_MESSAGE( str.str().c_str() ); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != limits::infinity() ); } { stringstream str; str << scientific << setprecision(50) << limits::max(); CPPUNIT_ASSERT(!str.fail()); CPPUNIT_CHECK( str.str() != "inf" ); CPPUNIT_CHECK( str.str() != "-inf" ); CPPUNIT_CHECK( str.str() != "nan" ); CPPUNIT_CHECK( str.str() != "-nan" ); //CPPUNIT_MESSAGE( str.str().c_str() ); //str.str(""); //str << limits::max_exponent10; //CPPUNIT_MESSAGE( str.str().c_str() ); str >> in_val_d; CPPUNIT_ASSERT(!str.fail()); CPPUNIT_ASSERT(str.eof()); CPPUNIT_CHECK( in_val_d == in_val_d ); CPPUNIT_CHECK( in_val_d != limits::infinity() ); }#endif { stringstream str; str << limits::infinity(); CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "inf" ); } { stringstream str; str << -limits::infinity(); CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( !limits::has_infinity || str.str() == "-inf" ); } { stringstream str; str << limits::quiet_NaN(); CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "nan" ); } { stringstream str; str << -limits::quiet_NaN(); CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( !limits::has_quiet_NaN || str.str() == "-nan" ); } { stringstream str; str << "0." << string(limits::max_exponent10, '0') << "1e" << (limits::max_exponent10 + 1); CPPUNIT_ASSERT( !str.fail() ); str >> in_val_d; CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( str.eof() ); CPPUNIT_CHECK( in_val_d == 1 ); } { stringstream str; str << "1" << string(-(limits::min_exponent10 - 1), '0') << "e" << (limits::min_exponent10 - 1); CPPUNIT_ASSERT( !str.fail() ); str >> in_val_d; CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( str.eof() ); CPPUNIT_CHECK( in_val_d == 1 ); }# if defined (_STLPORT_VERSION) && (_STLPORT_VERSION >= 0x530) // The following tests are showing that simply changing stream // precision lead to different result. Do not seems to be a real // problem, simply rounding approximation but additional study should // be done after 5.2 release. { stringstream str; str << setprecision(limits::digits10 + 2) << limits::max(); CPPUNIT_MESSAGE(str.str().c_str()); CPPUNIT_ASSERT( !str.fail() ); F val; str >> val; CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( limits::infinity() > val ); } { stringstream str; str << setprecision(limits::digits10 + 1) << limits::max(); CPPUNIT_MESSAGE(str.str().c_str()); CPPUNIT_ASSERT( !str.fail() ); F val; str >> val; CPPUNIT_ASSERT( !str.fail() ); CPPUNIT_ASSERT( limits::infinity() > val ); }# endif }#else# define __check_get_float( F ) \ void check_get_float( F v ) \ { \ F in_val_d = v; \ { \ stringstream str; \ \ str << "1E+" << numeric_limits<F>::max_exponent10; \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d != numeric_limits<F>::infinity() ); \ } \ { \ stringstream str; \ \ str << "-1E+" << numeric_limits<F>::max_exponent10; \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d != -numeric_limits<F>::infinity() ); \ } \ { \ stringstream str; \ \ str << "1E" << numeric_limits<F>::min_exponent10; \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d != F(0.0) ); \ } \ { \ stringstream str; \ \ str << "1E+" << (numeric_limits<F>::max_exponent10 + 1); \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d == numeric_limits<F>::infinity() ); \ } \ { \ stringstream str; \ \ str << "-1E+" << (numeric_limits<F>::max_exponent10 + 1); \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d == -numeric_limits<F>::infinity() ); \ } \ { \ stringstream str; \ \ str << "1E" << (numeric_limits<F>::min_exponent10 - 1); \ \ str >> in_val_d; \ CPPUNIT_ASSERT(!str.fail()); \ CPPUNIT_ASSERT(str.eof()); \ CPPUNIT_CHECK( in_val_d == in_val_d ); \ CPPUNIT_CHECK( in_val_d >= F(0.0) && in_val_d <= numeric_limits<F>::min() ); \ } \ } __check_get_float( float ) __check_get_float( double )# if !defined (STLPORT) || !defined (_STLP_NO_LONG_DOUBLE) __check_get_float( long double )# endif# undef __check_get_float#endif // _STLP_NO_MEMBER_TEMPLATES};CPPUNIT_TEST_SUITE_REGISTRATION(NumPutGetTest);#if defined (_MSC_VER)# pragma warning (disable : 4056)# pragma warning (disable : 4756)#endif//// tests implementation//void NumPutGetTest::num_put_float(){ { string output, digits; { ostringstream ostr; ostr << 1.23457e+17f; CPPUNIT_ASSERT(ostr.good()); output = reset_stream(ostr); digits = "17"; complete_digits(digits); CPPUNIT_CHECK(output == string("1.23457e+") + digits ); } { ostringstream ostr; ostr << setprecision(200) << 1.23457e+17f; CPPUNIT_ASSERT(ostr.good()); output = reset_stream(ostr); CPPUNIT_CHECK( output.size() < 200 ); } { ostringstream ostr; ostr << setprecision(200) << numeric_limits<float>::min(); CPPUNIT_ASSERT(ostr.good());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -