【问题标题】:Boost::Lexical_cast conversion to float changes dataBoost::Lexical_cast 转换为 float 更改数据
【发布时间】:2015-01-28 05:29:01
【问题描述】:

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

【问题讨论】:

  • 我认为你的全局变量 m_* 应该是 floats(并且你想在 test(1) 之前调用 test(0)
  • 哎呀,忘记编辑了,对不起。我正在阅读你的代码。谢谢你,嘿嘿。

标签: c++ boost floating-point lexical-cast


【解决方案1】:

问题是,有时您将拆分标记视为字符串(保持不变),有时您转换为浮点数。

到浮点数的转换创建了一个不精确二进制浮点表示。

为避免这种情况,请不要使用二进制浮点表示,而是使用具有足够精度的十进制表示来准确存储您的十进制输入表示。

使用,例如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)。此外,NaNInf 可能存在问题

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

【讨论】:

  • 好吧,似乎工作得很好,但我犯了一个错误:我只需要使用整数......所以,再次感谢你的关注。希望它会帮助别人!
猜你喜欢
  • 2015-03-25
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多