提升精神浮点数解析器的精度



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

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;
}

所以这可能是"float"类型解析器的限制/错误。尝试使用双语法分析器。

#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::双_:219721.03839999999036
qi::float_:219721.109375

最新更新