如何避免 `std::to_string()` 将非常小的双数变为 0?
How to avoid `std::to_string()` making a very small double number to 0?
我需要将非常小的双精度数字存储为字符串格式,然后再将它们反转。但是,当我尝试 运行 std::to_string()
像 4.7816457028269855e-143
这样的小数字时,它只是使它成为 0.
我提到了 Set precision of std::to_string when converting floating point values 及其链接副本。但是将精度设置为非常大的数字是否可以解决所有平台中的这个问题?
如何解决这个问题?
使用 to_string()
的任何替代方法都可以。
不对,问题不在于精度,而在于格式。您想以科学格式(带指数)打印,但 std::to_string()
默认使用固定格式,我不知道有什么方法可以更改它。
但是,流在适当的情况下使用科学,或者您可以使用 std::scientific
:
强制使用它
std::ostringstream oss;
oss << 4.7816457028269855e-143;
std::string numberAsString = oss.str(); // stores "4.78165e-143"
当然你还可以增加precision除此之外。
如果出于某种原因不想使用科学格式,可以使用精度足够高的固定格式。 “足够高”在这种情况下意味着超过 142,因为将有 142 个前导零:
oss << std::fixed << std::setprecision(142 + x);
但我想科学格式更适合。
如前所述,使用 std::to_string
无法实现此目的,但以足够大的精度将数字输出到 std::ostringstream
将解决您的问题。
可以使用 C++ 标准库工具以 cross-platform 方式计算所需的精度,特别是 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://possiblywrong.wordpress.com/2015/06/21/floating-point-round-trips/ 了解一些注意事项。
我需要将非常小的双精度数字存储为字符串格式,然后再将它们反转。但是,当我尝试 运行 std::to_string()
像 4.7816457028269855e-143
这样的小数字时,它只是使它成为 0.
我提到了 Set precision of std::to_string when converting floating point values 及其链接副本。但是将精度设置为非常大的数字是否可以解决所有平台中的这个问题?
如何解决这个问题?
使用 to_string()
的任何替代方法都可以。
不对,问题不在于精度,而在于格式。您想以科学格式(带指数)打印,但 std::to_string()
默认使用固定格式,我不知道有什么方法可以更改它。
但是,流在适当的情况下使用科学,或者您可以使用 std::scientific
:
std::ostringstream oss;
oss << 4.7816457028269855e-143;
std::string numberAsString = oss.str(); // stores "4.78165e-143"
当然你还可以增加precision除此之外。
如果出于某种原因不想使用科学格式,可以使用精度足够高的固定格式。 “足够高”在这种情况下意味着超过 142,因为将有 142 个前导零:
oss << std::fixed << std::setprecision(142 + x);
但我想科学格式更适合。
如前所述,使用 std::to_string
无法实现此目的,但以足够大的精度将数字输出到 std::ostringstream
将解决您的问题。
可以使用 C++ 标准库工具以 cross-platform 方式计算所需的精度,特别是 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://possiblywrong.wordpress.com/2015/06/21/floating-point-round-trips/ 了解一些注意事项。