以C++格式全精度显示浮点数



我已经阅读了几个关于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不一定是一回事。

最新更新