我正在从MySQL接收数据并尝试使用它。收到的数据位于m_caracs
,然后我尝试在其他float
中剪切此流的每个子部分。
让我们看看代码:
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <vector>
#include <string>
std::string m_sten;
std::string m_feal;
std::string m_felt;
std::string m_inte;
std::string m_sag;
std::string m_ende;
std::string m_asko;
std::string m_vit;
void test(bool mon)
{
std::string m_caracs = "f21.0i51.24v58.65c47.3s5.54d57.68e54.23h24.42";
if (mon == 0)
{
std::vector<std::string> charmps;
boost::split(charmps, m_caracs, boost::is_any_of("fivcsdeh"));
m_sten = boost::lexical_cast<float>(charmps[1]);
m_feal = boost::lexical_cast<float>(charmps[2]);
m_felt = boost::lexical_cast<float>(charmps[3]);
m_inte = boost::lexical_cast<float>(charmps[4]);
m_sag = boost::lexical_cast<float>(charmps[5]);
m_ende = boost::lexical_cast<float>(charmps[6]);
m_asko = boost::lexical_cast<float>(charmps[7]);
m_vit = boost::lexical_cast<float>(charmps[8]);
std::cout << m_caracs << std::endl;
}
else
{
std::cout << m_caracs << std::endl;
m_caracs = "f" + boost::lexical_cast<std::string>(m_sten) +
"i" + boost::lexical_cast<std::string>(m_feal) +
"v" + boost::lexical_cast<std::string>(m_felt) +
"c" + boost::lexical_cast<std::string>(m_inte) +
"s" + boost::lexical_cast<std::string>(m_sag) +
"d" + boost::lexical_cast<std::string>(m_ende) +
"e" + boost::lexical_cast<std::string>(m_asko) +
"h" + boost::lexical_cast<std::string>(m_vit);
std::cout << m_caracs << std::endl;
}
}
int main()
{
test(1);
test(0);
}
您可以看到f21.0i51.24v58.65c47.3s5.54d57.68e54.23h24.42
变为f21.0i51.24v58.65c47.3s5.54d57.68e54.23h24.42
。这正是我想要的。问题是,我有:
我不知道它来自哪里。唯一的变化是m_caracs
是从数据库接收的流。这是转换问题吗?
答案 0 :(得分:0)
问题在于,有一次你将拆分令牌视为字符串(保持不变),有时你会转换为浮点数。
转换为float会创建一个不精确的二进制浮点表示。
为了避免这种情况,请不要使用二进制浮点表示,而是使用具有足够精度的十进制表示来准确存储十进制输入表示。
使用,例如boost::multiprecision::cpp_dec_float
<强> Live On Coliru 强>
#include <boost/spirit/include/qi.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
namespace qi = boost::spirit::qi;
typedef boost::multiprecision::cpp_dec_float_50 Float;
int main()
{
std::string const m_caracs("f21.0i51.24v58.65c47.3s5.54d57.68e54.23h24.42");
std::cout << m_caracs << '\n';
Float m_sten, m_feal, m_felt, m_inte, m_sag, m_ende, m_asko, m_vit;
//auto num = qi::as_string[qi::raw[qi::double_]]; // this would parse exponents like 57.68e54
auto num = boost::proto::deep_copy(qi::as_string[+qi::char_("-+0-9.")]);
if (qi::parse(m_caracs.begin(), m_caracs.end(),
'f' >> num >> 'i' >> num >> 'v' >> num >>
'c' >> num >> 's' >> num >> 'd' >> num >>
'e' >> num >> 'h' >> num,
m_sten, m_feal, m_felt, m_inte, m_sag, m_ende, m_asko, m_vit
))
{
std::cout <<
'f' << m_sten <<
'i' << m_feal <<
'v' << m_felt <<
'c' << m_inte <<
's' << m_sag <<
'd' << m_ende <<
"e" << m_asko <<
'h' << m_vit << '\n';
}
}
PS 请注意输入格式也存在问题! 57.68e54
是有效的浮点数(例如lexical_cast
)。此外,NaN
或Inf
注意:在上面的示例中,您可能希望使用qi::real_parser<Float, custom_real_policies<Float> >
直接解析为cpp_dec_float
,而不是识别指数(如e54
)