Повышение точности анализатора плавающих чисел

Есть кое-что странное, что я заметил при сравнении boost :: lexical_cast и парсинга Boost Spirit.
Я пытаюсь разобрать строку в float. почему-то дух дает очень неточный результат. например: при разборе строки «219721.03839999999» с использованием lexical_cast я получаю 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

Решение

Так что, вероятно, это будет ограничение / ошибка парсера типа «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;
}

Выход:
Ци :: double_: +219721,03839999999036
Ци :: float_: 219721.109375

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]