diff --git a/modules/base/src/string_ref.cc b/modules/base/src/string_ref.cc index 46705256523ef07bd300cf016b19bc9f94056ed7..03209b11fabacadbff82daae3f36c80b1140f898 100644 --- a/modules/base/src/string_ref.cc +++ b/modules/base/src/string_ref.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #include <ost/string_ref.hh> +#include <math.h> namespace ost { @@ -53,6 +54,11 @@ std::pair<bool, float> StringRef::to_float() const int sig=1; bool after_dot=false; float factor=0.1; + bool after_exponent=false; + float exponent=0.0; + int exponent_sig=1; + bool after_exponent_sign=false; + for (const char* c=begin_; c!=end_; ++c) { if (*c=='-' && empty) { empty=false; @@ -71,17 +77,41 @@ std::pair<bool, float> StringRef::to_float() const if (after_dot==true) { n+=factor*int(*c-'0'); factor*=0.1; + } else if (after_exponent==true) { + exponent=exponent*10+int(*c-'0'); } else { n=n*10+int(*c-'0'); } continue; } + if ((*c=='+' || *c=='-') && after_exponent==true) { + if (after_exponent_sign==true) { + return std::make_pair(false, 0.0f); + } + if (*c=='-') { + exponent_sig=-1; + } + after_exponent_sign=true; + continue; + } + if (*c=='e' || *c=='E') { + if (after_exponent==true) { + return std::make_pair(false, 0.0f); + } + after_exponent=true; + after_dot=false; + continue; + } return std::make_pair(false, 0.0f); } if (empty) { return std::make_pair(false, 0.0f); } - return std::make_pair(true, sig*n); + if (after_exponent==false) { + return std::make_pair(true, sig*n); + } else { + return std::make_pair(true, sig*n*float(pow(10,exponent_sig*exponent))); + } } std::ostream& operator<<(std::ostream& stream, const StringRef& strref) diff --git a/modules/base/tests/test_string_ref.cc b/modules/base/tests/test_string_ref.cc index 50793bff7f83bde41e88047717d31687b7fbe5f8..05ea7701ec963d2d89f0c6098c9272e2cd59d3f2 100644 --- a/modules/base/tests/test_string_ref.cc +++ b/modules/base/tests/test_string_ref.cc @@ -84,6 +84,55 @@ BOOST_AUTO_TEST_CASE( test_string_ref) BOOST_CHECK(r2.first==false); r2=StringRef("12.34.", 6).to_float(); BOOST_CHECK(r2.first==false); + + // to_float_with_exp + std::pair<bool, Real> r3=StringRef("1", 1).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK(r3.second=1.0); + r3=StringRef("1.5", 3).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK(r3.second=1.5); + r3=StringRef("x", 1).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.3.4", 6).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.34.", 6).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.34e5", 7).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("12e4", 4).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(120000), Real(r3.second), Real(1e-4)); + r3=StringRef("2e+4", 4).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(20000), Real(r3.second), Real(1e-4)); + r3=StringRef("2.3E+4", 6).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(23000), Real(r3.second), Real(1e-4)); + r3=StringRef("2.3E-4", 6).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(0.00023), Real(r3.second), Real(1e-4)); + r3=StringRef("2.010000e+00", 12).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(2.01), Real(r3.second), Real(1e-4)); + r3=StringRef("5e-34", 5).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5E-34", 5).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5.34e-34", 8).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5.34e-34e", 9).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34ee34", 8).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e--34e", 10).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e+3+4", 9).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e-+34e", 10).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e-3-4", 9).to_float(); + BOOST_CHECK(r3.first==false); } BOOST_AUTO_TEST_SUITE_END()