将浮点数转换为指定精度和小数位数的字符串?
Convert float to string with precision & number of decimal digits specified?
在指定精度和小数位数的同时,如何在 C++ 中将浮点数转换为字符串?
例如: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();
Use fixed floating-point notation
Sets the floatfield
format flag for the str stream to fixed
.
When floatfield
is set to fixed
, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision
) and with no exponent part.
对于技术目的的转换,比如在XML或JSON文件中存储数据,C++17定义了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
}
做这种事的惯用方法是"print to string"。在 C++ 中,这意味着使用 std::stringstream
类似的东西:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
另一种选择是snprintf
:
double pi = 3.1415926;
std::string s(16, '[=10=]');
auto written = std::snprintf(&s[0], s.size(), "%.2f", pi);
s.resize(written);
Demo。应添加错误处理,即检查 written < 0
.
这里我提供了一个反面例子,你希望在将浮点数转换为字符串时避免这种情况。
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 或更新版本应提供第二个参数作为要显示的浮点数后的位数。现在默认值为 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();
}
你可以使用 C++20 std::format
:
#include <format>
int main() {
std::string s = std::format("{:.2f}", 3.14159265359); // s == "3.14"
}
或the {fmt} library, std::format
is based on (godbolt中的fmt::format
函数:
#include <fmt/core.h>
int main() {
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
其中 2
是精度。
它不仅比使用 iostreams 或 sprintf
更短,而且 significantly faster 并且不受语言环境的影响。
这里是一个只使用 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
该代码将整个浮点数转换为字符串,但在“.”之后将所有字符剪切 2 个字符
在指定精度和小数位数的同时,如何在 C++ 中将浮点数转换为字符串?
例如: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();
Use fixed floating-point notation
Sets the
floatfield
format flag for the str stream tofixed
.When
floatfield
is set tofixed
, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision
) and with no exponent part.
对于技术目的的转换,比如在XML或JSON文件中存储数据,C++17定义了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
}
做这种事的惯用方法是"print to string"。在 C++ 中,这意味着使用 std::stringstream
类似的东西:
std::stringstream ss;
ss << std::fixed << std::setprecision(2) << number;
std::string mystring = ss.str();
另一种选择是snprintf
:
double pi = 3.1415926;
std::string s(16, '[=10=]');
auto written = std::snprintf(&s[0], s.size(), "%.2f", pi);
s.resize(written);
Demo。应添加错误处理,即检查 written < 0
.
这里我提供了一个反面例子,你希望在将浮点数转换为字符串时避免这种情况。
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 或更新版本应提供第二个参数作为要显示的浮点数后的位数。现在默认值为 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();
}
你可以使用 C++20 std::format
:
#include <format>
int main() {
std::string s = std::format("{:.2f}", 3.14159265359); // s == "3.14"
}
或the {fmt} library, std::format
is based on (godbolt中的fmt::format
函数:
#include <fmt/core.h>
int main() {
std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14"
}
其中 2
是精度。
它不仅比使用 iostreams 或 sprintf
更短,而且 significantly faster 并且不受语言环境的影响。
这里是一个只使用 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
该代码将整个浮点数转换为字符串,但在“.”之后将所有字符剪切 2 个字符