我已经阅读了几个关于C++显示浮点数的主题,但我找不到令人满意的答案。
我的问题是: 如何以科学格式(尾数/指数)显示C++浮点数的所有有效数字?
问题是所有数字在 10 基数中没有相同数量的有效数字。
例如,一个double
具有 15 到 17 个有效的十进制数字精度,但std::numeric_limits<double>::digits10
返回 15,因此,对于某些数字,我将丢失 2 个额外的十进制数字精度。
值std::numeric_limits<double>::digits10
提供了可以安全恢复的十进制位数,即在往返十进制> double
->十进制中幸存下来的十进制位数。假设更多的十进制数字是正确的是没有帮助的。如果要促进往返double
->十进制-> double
,请使用std::numeric_limits<double>::max_digits10
。
如果你想要确切的值,你会使用std::numeric_limits<double>::digits
但它会以一种有趣的方式显示从十进制值转换的数字,因为它们通常是四舍五入的值。这也是为什么max_digits10
在呈现供人类消费的数字时没有用的原因:最后几位数字通常不是人类读者所期望的。
在 C++20 中,您可以使用 std::format
来执行此操作:
std::cout << std::format("{}", std::numbers::pi_v<double>);
输出(假设 IEEE 754 double
):
3.141592653589793
默认浮点格式是具有往返保证的最短十进制表示形式。与使用std::numeric_limits
max_digits10
精度相比,此方法的优点是它不会打印不必要的数字。例如:
std::cout << std::setprecision(
std::numeric_limits<double>::max_digits10) << 0.3;
打印0.29999999999999999
同时
std::cout << std::format("{}", 0.3);
打印0.3
(Godbolt)。
同时,您可以使用 {fmt} 库,std::format
基于。{FMT} 还提供了 print
函数,使这更容易、更高效(Godbolt):
fmt::print("{}", M_PI);
免责声明:我是{fmt}和C++20 std::format
的作者。
你看过std::max_digits10
吗?
从 cpp 首选项:
std::numeric_limits<T>::max_digits10
的值是 以 10 为基数的数字,是唯一表示所有不同数字所必需的 类型T
的值,例如 序列化/反序列化为文本。此常量对 所有浮点类型。
这意味着(也是我如何使用它)是文本输出可以复制/粘贴到另一个程序中,并且数字将代表相同的数字。
现在,我必须说,我的主力格式总是右对齐的%23.16E
,我对最后几位数字使用工程判断。我喜欢它,因为对于符号、指数和十六位数字来说已经足够了。
-----------------------
-1.1234567812345678E+12
现在,请注意,精度digits
和精度decimal digits
不一定是一回事。