如何在 C + + 中将浮点数转换为字符串,同时指定十进制数的精度和数目?
For example: 3.14159265359 -> "3.14"
3.14159265359 -> "3.14"
A typical way would be to use stringstream:
stringstream
#include <iomanip> #include <sstream> double pi = 3.14159265359; std::stringstream stream; stream << std::fixed << std::setprecision(2) << pi; std::string s = stream.str();
See 修好了
使用固定浮点表示法 将 STR流的 floatfield格式标志设置为 fixed。 当 floatfield设置为 fixed时,浮点值使用定点表示法写入: 该值在小数部分用与 精密场(precision)指定的一样多的数字表示,没有指数部分。
使用固定浮点表示法
将 STR流的 floatfield格式标志设置为 fixed。
floatfield
fixed
当 floatfield设置为 fixed时,浮点值使用定点表示法写入: 该值在小数部分用与 精密场(precision)指定的一样多的数字表示,没有指数部分。
precision
和 设定精度。
对于 技术用途转换,就像在 XML 或 JSON 文件中存储数据一样,C + + 17定义了 到 _ 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 }
做这类事情的通常方法是“打印到字符串”。在 C + + 中,这意味着使用 std::stringstream类似于:
std::stringstream
std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();
另一个选择是 snprintf:
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。
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。我提出这个假设是为了让其他人不要在这个问题上浪费时间。
我写了我的第一个版本,请让我知道,如果你发现任何错误,需要修复。你可以用操纵器控制精确的行为。我的函数是用来显示小数点后的位数。
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:
std::format
#include <format> int main() { std::string s = std::format("{:.2f}", 3.14159265359); // s == "3.14" }
或 { fmt }库的 fmt::format功能,std::format是基于(Godbolt) :
fmt::format
#include <fmt/core.h> int main() { std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }
其中 2是一个精度。
2
它不仅比使用 iostream 或 sprintf短,而且也比使用 significantly faster短,不受现场影响。
sprintf
这里的解决方案只使用标准。但是,请注意,这只是四舍五入。
float number = 3.14159; std::string num_text = std::to_string(number); std::string rounded = num_text.substr(0, num_text.find(".")+3);
对 rounded而言,其收益率为:
rounded
3.14
该代码将整个 float 转换为 string,但是在“”之后将所有字符删除2个字符