4

boost::lexical_cast とブースト スピリットの解析を比較すると、奇妙なことに気付きました。文字列をフロートに解析しようとしています。何らかの理由で、精神は非常に不正確な結果をもたらします。例: lexical_cast を使用して文字列 "219721.03839999999" を解析すると、219721.03 が得られますが、これはほぼ問題ありません。しかし、スピリットを使用すると(以下のコードを参照)、「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;
}
4

1 に答える 1

6

したがって、おそらく "float" 型パーサーの制限/バグでしょう。double_ パーサーを使用してみてください。

#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

于 2013-06-30T17:35:42.377 に答える