如何使用 cout 以全精度打印双精度值?
-
23-08-2019 - |
题
所以我已经得到了我的答案 最后一个问题 (我不知道为什么我没有想到这一点)。我正在打印一个 double
使用 cout
当我没有预料到的时候,它就被圆润了。我怎样才能使 cout
打印一个 double
使用全精度?
解决方案
可以在std::cout
直接设置精度和使用 std::fixed
格式说明符。
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
可以#include <limits>
得到一个浮动或双的最大精度。
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
其他提示
使用 std::setprecision
:
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
下面是我会用什么:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
基本上极限包具有用于类型所有构建性状。结果 一个性状为浮点数的(浮动/双/长双)是digits10属性。这定义了在基体10一个浮点数的准确性(I忘记确切的术语)。
请参阅: http://www.cplusplus.com/reference/std/限制/ numeric_limits.html 结果 有关其它属性的信息。
在输入输出流的方法是种笨重。我更喜欢使用 boost::lexical_cast
因为它计算正确的精度对我来说。和它的快速了。
#include <string>
#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
using std::string;
double d = 3.14159265358979;
cout << "Pi: " << lexical_cast<string>(d) << endl;
输出:
裨:3.14159265358979
下面是如何显示一个双具有全精度:
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 ::固定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>
通过全精度,我的意思是假定足够的精度,以显示到预期值的最佳近似,但应该指出的是,double
使用基座2表示和基座2不能代表微不足道尽可能精确1.1
东西存储。只有这样,才能得到的全满强>的实际双(没有舍入误差)是打印出的二进制位(或十六进制半字节)的精度。这样做的一种方式是写入double
到union
,然后打印出的位的整数值。
union {
double d;
uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;
这会给你双倍的100%准确的精度...而且是完全不可读,因为人类无法读取IEEE双格式! 维基百科具有良好的写了关于如何解释二进制位。
在较新的C ++,可以执行
std::cout << std::hexfloat << 1.1;
我如何打印
double
使用 cout 获得全精度值?
使用 hexfloat
或者
使用 scientific
并设置精度
std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific << 1.0/7.0 << '\n';
// C++11 Typical output
1.4285714285714285e-01
太多答案仅涉及 1)基础 2)固定/科学布局或 3)精度之一。太多的答案 精确 没有提供所需的正确值。因此这是对一个老问题的回答。
- 什么基地?
A double
当然是使用基数 2 进行编码的。使用 C++11 的直接方法是使用 std::hexfloat
.
如果非十进制输出可以接受,我们就完成了。
std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144
- 否则:
fixed
或者scientific
?
A double
是一个 浮点 类型,不 固定点.
做 不是 使用 std::fixed
因为这无法打印小 double
除了 0.000...000
. 。对于大型 double
, ,它可能会打印很多数字 数百 可疑的信息性。
std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000
要以完全精度打印,请首先使用 std::scientific
它将“以科学计数法写入浮点值”。请注意,默认小数点后 6 位,即金额不足,将在下一点处理。
std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43
- 精度是多少(总共有多少位)?
A double
使用二进制基数 2 编码在 2 的各个幂之间编码相同的精度。这通常是 53 位。
[1.0...2.0) 有 2 个53 不同的 double
,
[2.0...4.0) 有 2 个53 不同的 double
,
[4.0...8.0) 有 2 个53 不同的 double
,
[8.0...10.0) 有 2/8 * 253 不同的 double
.
然而,如果代码以十进制打印 N
有效数字,组合数 [1.0...10.0) 为 9/10 * 10氮.
任何 N
(精度)被选择,之间不会有一对一的映射 double
和十进制文本。 如果有一个固定的 N
被选择,有时会比某些特定的实际需要略多或略少 double
价值观。我们可能会因为太少而出错(a)
如下)或太多(b)
以下)。
3名候选人 N
:
a) 使用 N
所以当从文本转换时 -double
-text 我们为所有人得出相同的文本 double
.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) 使用 N
所以当从 double
-文本-double
我们达到相同的目标 double
对全部 double
.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
什么时候 max_digits10
不可用,请注意,由于基数 2 和基数 10 属性, digits10 + 2 <= max_digits10 <= digits10 + 3
, , 我们可以用 digits10 + 3
以确保打印足够的十进制数字。
c) 使用 N
这随值而变化。
当代码想要显示最少的文本(N == 1
) 或者 精确的 的值 double
(N == 1000-ish
如果是 denorm_min
)。然而,由于这是“工作”,不太可能是 OP 的目标,因此它将被搁置。
通常是b)用于“打印a double
具有完全精度的值”。某些应用程序可能更愿意 a) 不提供太多信息而出错。
和 .scientific
, .precision()
设置小数点后要打印的位数,因此 1 + .precision()
打印数字。代码需求 max_digits10
总位数所以 .precision()
被称为 max_digits10 - 1
.
typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific << exp (-100) << '\n';
std::cout << std::scientific << exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43
printf("%.12f", M_PI);
%。12F手段浮点,具有12位精度。
COUT是具有一堆可以调用来改变印刷的东西的精度和格式化方法中的对象。
有一个setprecision(...)操作,但你也可以设置其他的东西像打印宽度等。
在IDE的参考查找COUT。
大多数便携...
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;
使用的ostream ::精度(int)的
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
将产生
3.141592653589793, 2.718281828459045
为什么你不得不说“+1”我不知道,但你把它弄出来的额外的数字是正确的。