web-dev-qa-db-ja.com

精度と小数点以下の桁数を指定して、floatを文字列に変換しますか?

10進数の精度と数を指定しながら、C++でフロートを文字列に変換するにはどうすればよいですか?

例:3.14159265359 -> "3.14"

62
Shannon
#include <iomanip> // setprecision
#include <sstream> // stringstream
using namespace std;

double pi = 3.14159265359;
stringstream stream;
stream << fixed << setprecision(2) << pi;
string s = stream.str();

fixed を参照してください

固定浮動小数点表記を使用する

strストリームのfloatfield形式フラグをfixedに設定します。

floatfieldfixedに設定されている場合、浮動小数点値は固定小数点表記法を使用して書き込まれます。値は、精度フィールドで指定されたとおりの小数点以下の桁数で表現されますprecision)および指数部なし。

および setprecision

91
AlexD

この種のことを行うための慣習的な方法は、「文字列に出力する」ことです。 C++では、次のようなstd::stringstreamを使用することを意味します。

std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
24
Mats Petersson

別のオプションは snprintf

double pi = 3.1415926;

std::string s(16, '\0');
auto written = std::snprintf(&s[0], s.size(), "%.2f", pi);
s.resize(written);

デモ エラー処理、つまりwritten < 0を追加する必要があります。

9
Columbo

{fmt}ライブラリ からfmt::format関数を使用できます:

#include <fmt/core.h>

int main()
  std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}

ここで、2は精度です。

このフォーマット機能は、C++での標準化のために提案されています: P0645 。 P0645と{fmt}は両方とも、printfに似ているPythonのような形式文字列構文を使用しますが、{}の代わりに%を区切り文字として使用します。

3
vitaut

ここで、浮動小数点数を文字列に変換する際に避けたい負の例を示します。

float num=99.463;
float tmp1=round(num*1000);
float tmp2=tmp1/1000;
cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;

あなたが得る

99463 99.463 99.462997

注:num変数には、99.463に近い任意の値を指定できます。同じ印刷結果が得られます。ポイントは、便利なc ++ 11 "to_string"関数を避けることです。このtrapを抜け出すのに少し時間がかかりました。最良の方法は、stringstreamメソッドとsprintfメソッド(C言語)です。 C++ 11以降では、表示する浮動小数点の後の桁数として2番目のパラメーターを指定する必要があります。現在、デフォルトは6です。他の人がこのテーマについて時間を無駄にしないように、これを仮定しています。

最初のバージョンを書いたので、修正が必要なバグを見つけたら教えてください。 iomanipulatorで正確な動作を制御できます。私の機能は、小数点以下の桁数を表示することです。

string ftos(float f, int nd) {
   ostringstream ostr;
   int tens = stoi("1" + string(nd, '0'));
   ostr << round(f*tens)/tens;
   return ostr.str();
}
1
Kemin Zhou