我需要将非常小的双数存储为字符串格式,然后反转它们。然而,当我尝试在像
std::to_string()
这样的小数字上运行 4.7816457028269855e-143
时,它只会使其变为 0。
我提到了转换浮点值时设置 std::to_string 的精度及其链接的副本。但是将精度设置为很大的数字可以在所有平台上解决这个问题吗?
如何解决这个问题?
使用
to_string()
的任何替代品都可以。
不,问题不在于精度,而在于格式。您想以科学格式(带指数)打印,但
std::to_string()
默认使用固定格式,我不知道有什么方法可以改变它。
std::scientific
: 强制使用它
std::ostringstream oss;
oss << 4.7816457028269855e-143;
std::string numberAsString = oss.str(); // stores "4.78165e-143"
当然除此之外您还可以增加精度。
如果出于某种原因您不想使用科学格式,您可以使用精度足够高的固定格式。在这种情况下,“足够高”意味着超过 142,因为将有 142 个前导零:
oss << std::fixed << std::setprecision(142 + x);
但我认为科学格式更适合。
正如已经提到的,用
std::to_string
不可能实现这一点,但是以足够大的精度将数字输出到 std::ostringstream
将解决您的问题。
可以使用 C++ 标准库工具以跨平台方式计算所需的精度,特别是
std::numeric_limits<T>::max_digits10
常量:https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10
例如:
std::string to_string_exact(double x) {
std::ostringstream os;
os << std::setprecision(std::numeric_limits<double>::max_digits10) << x;
return os.str();
}
另请参阅https://possiblewrong.wordpress.com/2015/06/21/floating-point-round-trips/了解一些注意事项。
这是
std::to_string
的一个已知问题,已在 C++26 中修复。