對Boost庫中的數值到字串的轉換的改進 (轉)

worldblog發表於2007-12-13
對Boost庫中的數值到字串的轉換的改進 (轉)[@more@]

  Boost庫中的lexical_cast功能很強大,但存在一個浮點數的精度問題。在阿炯的《走進Boost》中描述如下:

  #include
  #include
  #include
 
  int main()
  {
  using std::string;
  const double d = 123.1234567;
  string s = boost::lexical_case(d);
  std::cout<  return 0;
  }

  以上預想的結果是得到:"123.1234567",但是實際上我們只會得到"123.123",因為預設情況下std::stringstream的精度是6。這算是boost::lexical_cast的一個。

  阿炯提供一個解決辦法:
  對頭作如下修改:
 //....
  template
  Target lexical_cast(Source arg) {
 //.....
  Target result;
  //以上一行是增加內容
  interpreter.precision(std::numeric_limits::digits10);
  if(!(interpreter<>result)||!(interpreter>>std::ws).eof())
 //.........
  }
<source>

  我按照上述方法在我的機器上怎麼也得不到正確結果。(BCB 6)
  就算可行的話,也存在以下問題:只能得到一種精度的字串。

  我使用以下方法解決以上的問題:

  利用C++中的函式過載機制,增加一個函式:
  template
  Target lexical_cast(Source arg)
  {
//......
  Target result;

  if(!(interpreter << arg) || !(interpreter >> result) ||
  !(interpreter >> std::ws).eof())
//....
  }

  template
//  下面一行修改了
  Target lexical_cast(Source arg,int length)
  {
# ifdef BOOST_LEXICAL_CAST_USE_STRSTREAM
  std::strstream interpreter; // for out-of-the-box g++ 2.95.2
# else
  std::stringstream interpreter;
# endif
  Target result;
// 增加下面一行
  interpreter.precision( length );
  if(!(interpreter << arg) || !(interpreter >> result) ||
  !(interpreter >> std::ws).eof())
  throw bad_lexical_cast();

  return result;
  }
}

  使用時如下:
 std::string s = boost::lexical_cast<:string>(123.1234567,10);
  即可以得到正確的結果,而且原來的函式不變。

小結

  不管多好的東西,總會有些小問題和不如意的東西,能夠自己動手加以改進,是很好的事。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992543/,如需轉載,請註明出處,否則將追究法律責任。

相關文章