1

我正在从 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从数据库接收到的流。那是转换问题吗?

4

1 回答 1

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是一个有效的浮点数(例如 for lexical_cast)。此外,可能存在问题NaNInf

注意:在上面的示例中,您可能希望使用qi::real_parser<Float, custom_real_policies<Float> >直接解析为 a cpp_dec_float,而不是识别指数(如e54

于 2015-01-28T07:22:56.113 回答