精度と小数点以下の桁数を指定しながら、C ++でfloatを文字列に変換するにはどうすればよいですか?
例えば: 3.14159265359 -> "3.14"
精度と小数点以下の桁数を指定しながら、C ++でfloatを文字列に変換するにはどうすればよいですか?
例えば: 3.14159265359 -> "3.14"
回答:
典型的な方法は、以下を使用することstringstream
です。
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
修正済みを参照
固定浮動小数点表記を使用する
strストリームの
floatfield
フォーマットフラグをに設定しますfixed
。
floatfield
がに設定されている場合fixed
、浮動小数点値は固定小数点表記を使用して書き込まれます。値は、精度フィールド(precision
)で指定された小数部の桁数で表され、指数部分はありません。
およびsetprecision。
ために 技術的な目的の変換、C ++ 17の定義するXMLまたはJSONファイル内のデータを格納するように、to_chars機能の家族を。
準拠したコンパイラ(執筆時点では不足しています)を想定すると、次のようなものが考えられます。
#include <array>
#include <charconv>
double pi = 3.14159265359;
std::array<char, 128> buffer;
auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi,
std::chars_format::fixed, 2);
if (ec == std::errc{}) {
std::string s(buffer.data(), ptr);
// ....
}
else {
// error handling
}
snprintf
この場合、なぜより良いのでしょうか?説明してください...確かに高速ではなく、生成されるコードも少なくなります[printf実装を作成しました。コードは2000行弱でかなりコンパクトですが、マクロ展開では約2500行になります]
__printf_fp
機能を使用しているように見えます-stringstream
実際にそうする必要がないので、それが非常に長くかかるのはかなり奇妙です。
{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
'sに似ていますが{}
、の代わりに区切り文字として使用するPythonのようなフォーマット文字列構文を使用し%
ます。
ここでは、stdのみを使用したソリューションです。ただし、これは切り捨てられるだけであることに注意してください。
float number = 3.14159;
std::string num_text = std::to_string(number);
std::string rounded = num_text.substr(0, num_text.find(".")+3);
rounded
それが得られます。
3.14
このコードはfloat全体を文字列に変換しますが、「。」の2文字後にすべての文字を切り取ります。
number + 0.005
私の場合。
ここでは、浮動小数点数を文字列に変換するときに避けたいという否定的な例を示しています。
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"関数を避けることです。この罠から抜け出すのに少し時間がかかりました。最良の方法は、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();
}