如果可以使用外部库来实现此目标,则可以选择
fmtlib(该库可能会进入标准库),它声称比其他方法更快(请参见其
基准测试)。
#include <fmt/format.h>
std::string FloatToScientificString(float val, int width, int precision)
{
return fmt::format("{:>{}.{}e}", val, width, precision);
}
这应该返回一个与您原来的函数完全相同的字符串,并且与 std::*printf
方法一样,不会牺牲类型安全性。当使用abseil替代时(他们声称比printf
系列更快),该函数如下所示:
#include <absl/strings/str_format.h>
std::string FloatToScientificString(float val, int width, int precision)
{
return absl::StrFormat("%*.*e", width, precision, val);
}
还有 boost format,它不允许将宽度或精度说明符作为参数传递,但这同样有效:
#include <boost/format.hpp>
std::string FloatToScientificString(float val, int width, int precision)
{
const std::string fmt = "%" + std::to_string(width) + "." +
std::to_string(precision) + "e";
return boost::str(boost::format(fmt) % val);
}
最后,没有使用除标准库以外的任何外部依赖(请注意,使用 std::snprintf
要优于 std::sprintf
,因为可以检查缓冲区大小,但两个函数都不具备类型安全性):
#include <cstdio>
std::string FloatToScientificString(float val, int width, int precision)
{
static const int bufSize = 100;
static char buffer[bufSize];
std::snprintf(buffer, bufSize, "%*.*e", width, precision, val);
return std::string(buffer);
}
正确分析这些选项可能是一个单独的主题。不过,任何这些选项都应该比使用 std::stringstream
的原始方法快得多,除了 std::snprintf
之外的所有代码片段都是类型安全的。
sprintf(buf, "%*.*e", width, precision, val)
)来加快速度。 - Serge Ballesta