3

ptree をプログラミングしていて、ある時点で 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

このエラーの原因と解決方法を教えてください。

4

1 に答える 1

3

デフォルトで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 を使用すると、以下が出力されます。

最小=-1.797693134862316e+308

最大 = 1.797693134862316e+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;
           }
        }
      };
    }
    
于 2012-12-04T23:05:03.067 に答える