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