用C ++完全精确显示浮点数?

时间:2013-10-26 18:12:41

标签: c++ floating-point iostream floating-point-precision iomanip

我已经阅读了几个关于在C ++中显示浮点数的主题,我找不到令人满意的答案。

我的问题是: 如何以科学格式(尾数/指数)显示C ++中浮点数的所有有效数字?

问题是所有数字在基数10中的有效位数不同。

例如,double 15到17 有效十进制数字精度,但std::numeric_limits<double>::digits10返回15,因此,对于某些数字,我将丢失2个额外十进制数字的精度

3 个答案:

答案 0 :(得分:5)

std::numeric_limits<double>::digits10提供可以安全恢复的小数位数,即在往返小数中保持的小数位数 - &gt; double - &gt;十进制。假设更多十进制数字是正确的没有帮助。如果您想方便往返double - >小数 - > double,您可以使用std::numeric_limits<double>::max_digits10

如果你想要使用std::numeric_limits<double>::digits的确切值,但它会以有趣的方式显示从十进制值转换的数字,因为它们通常是舍入值。这也是max_digits10在为人类消费提供数字时没有用的原因:最后几位通常不是人类读者所期望的数字。

答案 1 :(得分:2)

你看过std::max_digits10了吗?

来自cppreference

  

std::numeric_limits<T>::max_digits10的值是   基数为10位数,是唯一表示所有不同的数字   T类型的值,例如必要的值   序列化/反序列化到文本。这个常数对于有意义   所有浮点类型。

这个(以及我如何使用它)的含义是文本输出可以复制/粘贴到另一个程序中,该数字代表相同的数字

现在,我必须说我的工作马格式始终是正确的%23.16E,我使用工程判断来表示最后几位数字。我喜欢它因为符号,指数和十六位数就足够了。

-----------------------
-1.1234567812345678E+12

现在,请注意digits精度和decimal digits精度不一定相同。

答案 2 :(得分:1)

在C ++ 20中,您将可以使用std::format来做到这一点:

std::cout << std::format("{}", M_PI);

输出(假设IEEE754 double):

3.141592653589793

默认浮点格式是带有往返保证的最短十进制表示形式。与使用max_digits10中的std::numeric_limits的精度相比,此方法的优势在于它不会打印不必要的数字。例如:

std::cout << std::setprecision(
  std::numeric_limits<double>::max_digits10) << 0.3;

同时打印0.29999999999999999

std::cout << std::format("{}", 0.3);

打印0.3godbolt)。

在此期间,您可以使用the {fmt} librarystd::format是基于。 {fmt}还提供了print功能,使此操作变得更加轻松和高效(godbolt):

fmt::print("{}", M_PI);

免责声明:我是{fmt}和C ++ 20 std::format的作者。