2012-11-30 66 views
2

我正在編程一個ptree,並且在某些時候我需要將DBL_MAX放入(作爲默認值)。 我打開生成的xml文件時看到了正確的數字。boost屬性樹put/get DBL_MAX

但是當我使用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精度轉換:當其轉換​​到std::string,因爲它舍入到一個無效的值號碼出現

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

此問題。你可以用下面的代碼檢查:

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

但是,​​定義爲1.7976931348623158e+308,因此打印值超出限制。

有幾種解決方法,但並不完美:

  • 使用不同的默認值小於​​。例如1.797693134862315e+308
  • 捕獲bad_data異常,並假定它表示默認。
  • 用您的自定義轉換器註冊一個新類型。你可以看到一個例子here
  • 降低存儲值的精度。您可以使用下面的代碼執行此:

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

感謝很多答案。這真的很有幫助。 :) – Annah