如何在C++中将浮点数转换为字符串,同时指定精度和小数位数?例如:3.14159265359 -> "3.14"
3.14159265359 -> "3.14"
jw5wzhpr1#
典型的方法是使用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();
参见fixed
使用固定浮点表示法
将 str 流的floatfield标志设置为fixed。当floatfield设置为fixed时,使用定点表示法写入浮点值:该值用与 *precision字段 *(precision)所指定的小数部分中的数字一样多的数字来表示,并且没有指数部分。setprecision。对于技术目的的转换,例如将数据存储在XML或JSON文件中,C++17定义了to_chars函数家族。假设有一个兼容的编译器(我们在写这篇文章的时候还没有),可以考虑这样的东西:
floatfield
fixed
precision
#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 }
hec6srdp2#
做这类事情的习惯方法是“打印到字符串”。在C++中,这意味着使用std::stringstream如下:
std::stringstream
std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();
x8goxv8g3#
可以使用C++20 std::format:
std::format
#include <format> int main() { std::string s = std::format("{:.2f}", 3.14159265359); // s == "3.14" }
或者来自the {fmt} library,std::format的fmt::format函数基于(godbolt):
fmt::format
#include <fmt/core.h> int main() { std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }
其中2是精度。它不仅比使用iostreams或sprintf更短,而且速度明显更快,并且不受语言环境的影响。
2
sprintf
pb3skfrl4#
另一个选项是snprintf:
snprintf
double pi = 3.1415926; std::string s(16, '\0'); auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); s.resize(written);
Demo。应添加错误处理,即检查written < 0。
written < 0
vi4fp9gy5#
这里只使用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,它产生:
rounded
3.14
代码将整个浮点数转换为字符串,但将“”后2个字符处的所有字符删除。
x3naxklr6#
在这里,我提供了一个负面的例子,你想避免在转换浮点数字符串。
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的任何值,你将得到相同的打印输出。关键是避免方便的c11“to_string”函数。我花了一段时间才摆脱这个陷阱。最好的方法是stringstream和sprintf方法(C语言)。C11或更高版本应该提供第二个参数作为浮点数后的位数来显示。现在默认值是6。我这样做是为了让其他人不会在这个问题上浪费时间。我写了我的第一个版本,请让我知道,如果你发现任何需要修复的bug。你可以控制与iomanipulator的确切行为。我的功能是显示小数点后的位数。
string ftos(float f, int nd) { ostringstream ostr; int tens = stoi("1" + string(nd, '0')); ostr << round(f*tens)/tens; return ostr.str(); }
6条答案
按热度按时间jw5wzhpr1#
典型的方法是使用
stringstream
:参见fixed
使用固定浮点表示法
将 str 流的
floatfield
标志设置为fixed
。当
floatfield
设置为fixed
时,使用定点表示法写入浮点值:该值用与 *precision字段 *(precision
)所指定的小数部分中的数字一样多的数字来表示,并且没有指数部分。setprecision。
对于技术目的的转换,例如将数据存储在XML或JSON文件中,C++17定义了to_chars函数家族。
假设有一个兼容的编译器(我们在写这篇文章的时候还没有),可以考虑这样的东西:
hec6srdp2#
做这类事情的习惯方法是“打印到字符串”。在C++中,这意味着使用
std::stringstream
如下:x8goxv8g3#
可以使用C++20
std::format
:或者来自the {fmt} library,
std::format
的fmt::format
函数基于(godbolt):其中
2
是精度。它不仅比使用iostreams或
sprintf
更短,而且速度明显更快,并且不受语言环境的影响。pb3skfrl4#
另一个选项是
snprintf
:Demo。应添加错误处理,即检查
written < 0
。vi4fp9gy5#
这里只使用std的解决方案。但是,请注意,这只是向下舍入。
对于
rounded
,它产生:代码将整个浮点数转换为字符串,但将“”后2个字符处的所有字符删除。
x3naxklr6#
在这里,我提供了一个负面的例子,你想避免在转换浮点数字符串。
你得到
注意事项:num变量可以是接近99.463的任何值,你将得到相同的打印输出。关键是避免方便的c11“to_string”函数。我花了一段时间才摆脱这个陷阱。最好的方法是stringstream和sprintf方法(C语言)。C11或更高版本应该提供第二个参数作为浮点数后的位数来显示。现在默认值是6。我这样做是为了让其他人不会在这个问题上浪费时间。
我写了我的第一个版本,请让我知道,如果你发现任何需要修复的bug。你可以控制与iomanipulator的确切行为。我的功能是显示小数点后的位数。