📄 converter_test.cpp
字号:
c_neg_overflow, c_converted, c_converted, c_converted, c_converted ) ; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::Trunc<S>), max, c_converted, c_converted, c_converted, c_converted, c_pos_overflow ) ; cout << "Testing 'RoundEven' Float2IntRounder policy\n"; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::RoundEven<S>), min, c_neg_overflow, c_converted, c_converted, c_converted, c_converted ) ; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::RoundEven<S>), max, c_converted, c_converted, c_converted, c_pos_overflow, c_pos_overflow ) ; cout << "Testing 'Ceil' Float2IntRounder policy\n"; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::Ceil<S>), min, c_neg_overflow, c_converted, c_converted, c_converted, c_converted ) ; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::Ceil<S>), max, c_converted, c_converted, c_converted, c_pos_overflow, c_pos_overflow ) ; cout << "Testing 'Floor' Float2IntRounder policy\n" ; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::Floor<S>), min, c_neg_overflow, c_neg_overflow, c_converted, c_converted, c_converted ) ; test_rounding_conversion(SET_FNTPL_ARG(T), SET_FNTPL_ARG(boost::numeric::Floor<S>), max, c_converted, c_converted, c_converted, c_converted, c_pos_overflow ) ;}void test_round_even( double n, double x ){ double r = boost::numeric::RoundEven<double>::nearbyint(n); BOOST_CHECK( r == x ) ;}void test_round_even(){ cout << "Testing 'RoundEven' tie-breaking\n"; double min = boost::numeric::bounds<double>::lowest(); double max = boost::numeric::bounds<double>::highest();#if !defined(BOOST_NO_STDC_NAMESPACE) using std::floor ; using std::ceil ;#endif test_round_even(min, floor(min)); test_round_even(max, ceil (max)); test_round_even(2.0, 2.0); test_round_even(2.3, 2.0); test_round_even(2.5, 2.0); test_round_even(2.7, 3.0); test_round_even(3.0, 3.0); test_round_even(3.3, 3.0); test_round_even(3.5, 4.0); test_round_even(3.7, 4.0);}int double_to_int ( double n ) { return static_cast<int>(n) ; }void test_converter_as_function_object(){ cout << "Testing converter as function object.\n"; // Create a sample sequence of double values. std::vector<double> S ; for ( int i = 0 ; i < 10 ; ++ i ) S.push_back( i * ( 18.0 / 19.0 ) ); // Create a sequence of int values from 's' using the standard conversion. std::vector<int> W ; std::transform(S.begin(),S.end(),std::back_inserter(W),double_to_int); // Create a sequence of int values from s using a default numeric::converter std::vector<int> I ; std::transform(S.begin(), S.end(), std::back_inserter(I), boost::numeric::converter<int,double>() ) ; // Match 'w' and 'i' which should be equal. bool double_to_int_OK = std::equal(W.begin(),W.end(),I.begin()) ; BOOST_CHECK_MESSAGE(double_to_int_OK, "converter (int,double) as function object"); // Create a sequence of double values from s using a default numeric::converter (which should be the trivial conv). std::vector<double> D ; std::transform(S.begin(), S.end(), std::back_inserter(D), boost::numeric::converter<double,double>() ) ; // Match 's' and 'd' which should be equal. bool double_to_double_OK = std::equal(S.begin(),S.end(),D.begin()) ; BOOST_CHECK_MESSAGE(double_to_double_OK, "converter (double,double) as function object");}#if BOOST_WORKAROUND(__IBMCPP__, <= 600 ) // VCAPP6# define UNOPTIMIZED#else# define UNOPTIMIZED volatile#endifvoid test_optimizations(){ using namespace boost; using namespace numeric; float fv0 = 18.0f / 19.0f ; // This code deosn't produce any output. // It is intended to show the optimization of numeric::converter<> by manual inspection // of the generated code. // Each test shows first the equivalent hand-coded version. // The numeric_cast<> code should be the same if full compiler optimization/inlining is used. //--------------------------------- // trivial conversion. // // equivalent code: UNOPTIMIZED float fv1a = fv0 ; float fv1b = numeric_cast<float>(fv0); unused_variable(fv1a); unused_variable(fv1b); // //--------------------------------- //--------------------------------- // nonsubranged conversion. // // equivalent code: UNOPTIMIZED double dv1a = static_cast<double>(fv0); double dv1b = numeric_cast<double>(fv0); unused_variable(dv1a); unused_variable(dv1b); // //--------------------------------- //------------------------------------------------------ // subranged conversion with both-sided range checking. // // equivalent code: { double const& s = dv1b ; // range checking range_check_result r = s < static_cast<double>(bounds<float>::lowest()) ? cNegOverflow : cInRange ; if ( r == cInRange ) { r = s > static_cast<double>(bounds<float>::highest()) ? cPosOverflow : cInRange ; } if ( r == cNegOverflow ) throw negative_overflow() ; else if ( r == cPosOverflow ) throw positive_overflow() ; // conversion UNOPTIMIZED float fv2a = static_cast<float>(s); unused_variable(fv2a); } float fv2b = numeric_cast<float>(dv1b); unused_variable(fv2b); // //--------------------------------- //--------------------------------- // subranged rounding conversion // // equivalent code: { double const& s = dv1b ; // range checking range_check_result r = s <= static_cast<double>(bounds<int>::lowest()) - static_cast<double>(1.0) ? cNegOverflow : cInRange ; if ( r == cInRange ) { r = s >= static_cast<double>(bounds<int>::highest()) + static_cast<double>(1.0) ? cPosOverflow : cInRange ; } if ( r == cNegOverflow ) throw negative_overflow() ; else if ( r == cPosOverflow ) throw positive_overflow() ; // rounding#if !defined(BOOST_NO_STDC_NAMESPACE) using std::floor ;#endif double s1 = floor(dv1b + 0.5); // conversion UNOPTIMIZED int iv1a = static_cast<int>(s1); unused_variable(iv1a); } int iv1b = numeric_cast<int>(dv1b); unused_variable(iv1b); // //---------------------------------}int test_main( int, char* argv[] ){ std::cout << std::setprecision( std::numeric_limits<long double>::digits10 ) ; test_conversions(); test_overflow_handlers( SET_FNTPL_ARG(boost::int16_t), SET_FNTPL_ARG(boost::int32_t)); test_round_style(SET_FNTPL_ARG(boost::int32_t), SET_FNTPL_ARG(double) ) ; test_round_even() ; test_converter_as_function_object(); test_optimizations() ; return 0;}//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -