本文介绍了提高Spirit浮点数解析器的精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在比较boost :: lexical_cast和boost精神分析时,我注意到了一件奇怪的事情.我正在尝试将字符串解析为float.由于某种原因,精神产生了非常不精确的结果.例如:当使用lexical_cast解析字符串"219721.03839999999"时,我得到219721.03或多或少可以.但是当我使用Spirit时(请参见下面的代码),我得到的是"219721.11",这远不是确定的.知道为什么会发生吗?

There is something strange I noticed when comparing boost::lexical_cast and boost spirit parsing.I'm trying to parse a string into float. for some reason spirit gives very imprecise result. for example: when parsing string "219721.03839999999" using lexical_cast i get 219721.03 which is more or less OK. but when I use spirit (see code below) I get "219721.11" which is far from bein OK. Any idea why it happens?

template<>
inline float LexicalCastWithTag(const std::string& arg)
{
    float result = 0;

    if(arg.empty())
    {
        throw BadLexicalCast("Cannot convert from to std::string to float");
    }

    auto itBeg = arg.begin();
    auto itEnd = arg.end();

    if(!boost::spirit::qi::parse(itBeg, itEnd, boost::spirit::qi::float_, result) || itBeg != itEnd)
    {
        throw BadLexicalCast("Cannot convert from to std::string to float");
    }

    return result;
}

推荐答案

因此,它可能是浮动"类型解析器的限制/错误.尝试使用double_解析器.

So it will be probably limitation/bug of "float" type parser. Try to use double_ parser.

#include<iostream>
#include<iomanip>
#include<string>
#include<boost/spirit/include/qi.hpp>

int main()
{
    std::cout.precision(20);

    //float x=219721.03839999999f;  
    //std::cout << x*1.0f << std::endl;  
    //gives 219721.03125  

    double resultD;
    std::string arg="219721.03839999999";

    auto itBeg = arg.begin();
    auto itEnd = arg.end();
    if(!boost::spirit::qi::parse(itBeg, itEnd,boost::spirit::qi::double_,resultD) || itBeg != itEnd)
        std::cerr << "Cannot convert from std::string to double" << std::endl;
    else
        std::cout << "qi::double_:" << resultD << std::endl;

    float resultF;
    itBeg = arg.begin();
    itEnd = arg.end();
    if(!boost::spirit::qi::parse(itBeg, itEnd,boost::spirit::qi::float_,resultF) || itBeg != itEnd)
        std::cerr << "Cannot convert from std::string to float" << std::endl;
    else
        std::cout << "qi::float_ :" << resultF << std::endl;

    return 0;
}

输出:
qi :: double_:219721.03839999999036
qi :: float_:219721.109375

Output:
qi::double_:219721.03839999999036
qi::float_:219721.109375

这篇关于提高Spirit浮点数解析器的精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-23 05:42