увеличить / увеличить дерево свойств DBL_MAX

Я программирую дерево и в какой-то момент мне нужно поместить DBL_MAX (в качестве значения по умолчанию).
Я вижу правильное число, когда открываю сгенерированный xml-файл.

Но когда я использую ptree.get для получения номера, выдается исключение:conversion of data to type "d" failed

Вот мой код:

using boost::property_tree::ptree;
ptree pt;

double d=-DBL_MAX;
double d2=-1.797693134862316e+308;
double d3=-1.79769e+308;

cout<<d<<endl;
cout<<d2<<endl;
cout<<d3<<endl;

pt.put<double>("double", d);
write_xml("test.xml", pt);

cout << "totalEndTimeLowerBound: " << pt.get<double>("double")<<endl;
//doesn't work with d and d2, but works with d3

Что может вызвать эту ошибку и как я могу ее устранить?

2

Решение

По умолчанию, ptree сохраняет свои значения как std::string и конвертировать их, используя basic_stringstream с точностью:

s.precision(std::numeric_limits<double>::digits10+1);

Эта проблема появляется при конвертации DBL_MAX в std::string потому что округляет число до недопустимого значения. Вы можете проверить это с помощью следующего кода:

ptree pt;
pt.put("min", -DBL_MAX);
pt.put("max", DBL_MAX);
cout << "Min=" << pt.get<string>("min") << std::endl;
cout << "Max=" << pt.get<string>("max") << std::endl;

Используя Visual Studio, он печатает:

Min = -1.797693134862316e + 308

Макс = 1,779693134862316e + 308

Тем не мение, DBL_MAX определяется как 1.7976931348623158e+308 таким образом, напечатанное значение выходит за пределы.

Есть несколько обходных путей, но ни один не идеален:

  • Используйте другое значение по умолчанию, меньшее, чем DBL_MAX, Например 1.797693134862315e+308,
  • Поймать bad_data исключение и предположим, что это означает по умолчанию.
  • Зарегистрируйте новый тип с помощью пользовательского конвертера. Вы можете увидеть пример Вот.
  • Уменьшите точность сохраненного значения. Вы можете выполнить это, используя следующий код:

    namespace boost { namespace property_tree
    {
    template <typename Ch, typename Traits>
    struct customize_stream<Ch, Traits, double, void>
    {
    static void insert(std::basic_ostream<Ch, Traits>& s, const double& e) {
    s.precision(std::numeric_limits<double>::digits10-1);
    s << e;
    }
    static void extract(std::basic_istream<Ch, Traits>& s, double& e) {
    s >> e;
    if(!s.eof()) {
    s >> std::ws;
    }
    }
    };
    }
    
2

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

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

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector