在我之前的问题中,我打印了一个double using cout,当我没有预料到它时,它变得圆润了。我如何才能使cout打印一个双重使用全精度?
当前回答
下面是如何完全精确地显示double值:
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
这将显示:
100.0000000000005
Max_digits10是唯一表示所有不同双精度值所需的位数。Max_digits10表示小数点前后的位数。
不要在std::fixed中使用set_precision(max_digits10)。 在固定表示法中,set_precision()只设置小数点后的位数。这是不正确的,因为max_digits10表示小数点前后的位数。
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;
显示错误的结果:
100.00000000000049738
注意:需要头文件
#include <iomanip>
#include <limits>
其他回答
printf("%.12f", M_PI);
%。12f表示浮点数,精度为12位。
在c++ 20中,你可以使用std::format来做到这一点:
std::cout << std::format("{}", M_PI);
输出(假设双IEEE754):
3.141592653589793
默认浮点格式是具有往返保证的最短十进制表示形式。与setprecision I/O操纵符相比,这种方法的优点是它不会打印不必要的数字。
在此期间,您可以使用{fmt}库,std::format是基于。{fmt}还提供了print函数,使这更容易和更有效(godbolt):
fmt::print("{}", M_PI);
免责声明:我是{fmt}和c++ 20 std::format的作者。
上ostream::精密(int)
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
将产生
3.141592653589793, 2.718281828459045
为什么说“+1”我不知道,但你多出来的数字是正确的。
c++ 20 std::格式
这个伟大的c++库新特性的优点是不会像std::setprecision那样影响std::cout的状态:
#include <format>
#include <string>
int main() {
std::cout << std::format("{:.2} {:.3}\n", 3.1415, 3.1415);
}
预期的输出:
3.14 3.142
正如https://stackoverflow.com/a/65329803/895245中提到的,如果不显式传递精度,它会打印带有往返保证的最短十进制表示。TODO更详细地了解它与:dbl::max_digits10的比较,如https://stackoverflow.com/a/554134/895245中显示的{:.{}}:
#include <format>
#include <limits>
#include <string>
int main() {
std::cout << std::format("{:.{}}\n",
3.1415926535897932384626433, dbl::max_digits10);
}
参见:
返回c++中的默认浮点打印精度,以了解如何恢复pre-c++20中的初始精度 Std::string格式,如sprintf https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification
在这个问题中,有一个关于如何无损地将double类型转换为字符串的描述(在Octave中,但它可以很容易地在c++中重现)。我们的想法是对浮点数有一个人类可读的简短描述和一个十六进制形式的无损描述,例如:pi -> 3.14{54442d18400921fb}。