当前位置:  开发笔记 > 编程语言 > 正文

如何使用cout以完全精度打印双精度值?

如何解决《如何使用cout以完全精度打印双精度值?》经验,为你挑选了7个好方法。

所以我已经得到了我最后一个问题的答案(我不知道为什么我没有想到这一点).当我没想到它的时候,我正在打印一个圆润的double使用cout.如何使用全精度cout打印double



1> Bill the Liz..:

您可以直接设置精度std::cout并使用std::fixed格式说明符.

double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;

#include 可以获得浮点数或双精度的最大精度.

#include 

typedef std::numeric_limits< double > dbl;

double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;


为什么你明确建议使用`fixed`?用`double h = 6.62606957e-34;`,`fixed`给我'0.000000000000000`和`scientific`输出`6.626069570000000e-34`.
精度需要为17(或std :: numeric_limits :: digits10 + 2),因为从十进制转换回二进制表示时需要2个额外的数字,以确保将值四舍五入为相同的原始值.这是一篇包含一些细节的论文:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
@MikeFisher你是对的,[C++ 11引入了`max_digits10`](http://www2.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf)来表示相同的.修正了反映这一点的答案.
真的是正确答案吗?当我手动使用一个高数字时,我可以打印出多达51个近似e的数字,但是用`cout.precision(numeric_limits :: digits10 + 2);`我只得到16 ....
对于那些在@MikeFisher引用的论文中提到17位数字的人来说,它属于定理15.
设置精度也适用于stringstream对象
`max_digits10`可能对设置科学计数法显示的数字有用; 对于固定,它仅适用于幅度接近1的值.
@chux确实,使用float时,我们有6位数和9位数。但是在x87上使用“ long double”(全精度,例如在GCC中)时,我们也有18位数和21位数,以及`float128`(IEEE754`binary128`):33位数和36位数。因此,是“ double”(其最小和最大值分别为15位数和17位数)。

2> Paul Becking..:

用途std::setprecision:

std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;


的std :: setprecision(标准:: numeric_limits <双> :: digits10)
要使std :: setprecision工作,应包括#include .
应该是`std :: setprecision(17)`for double,请参阅@Bill对Lizard的回答的评论.
是否有某种MAX_PRECISION宏或枚举,或者可以传递给std :: setPrecision的东西?
std :: setprecision(15)表示double(ok或16),log_10(2**53)〜= 15.9

3> Martin York..:

这是我会用的:

std::cout << std::setprecision (std::numeric_limits::digits10 + 1)
          << 3.14159265358979
          << std::endl;

基本上,限制包具有所有类型的内置特征.
浮点数(float/double/long double)的特征之一是digits10属性.这定义了基数10中浮点数的准确性(我忘记了确切的术语).

请参阅:http://www.cplusplus.com/reference/std/limits/numeric_limits.html
有关其他属性的详细信息.


使用`std :: setprecision()`:`#include `需要这个头
@LokiAstari您可以使用C + 11的`max_digits10`代替.见[this](http://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout/554134#comment52239614_554134).

4> Timothy003..:

iostreams的方式有点笨重.我更喜欢使用,boost::lexical_cast因为它为我计算了正确的精度.而它的快速,太.

#include 
#include 

using boost::lexical_cast;
using std::string;

double d = 3.14159265358979;
cout << "Pi: " << lexical_cast(d) << endl;

输出:

Pi:3.14159265358979



5> Mark Lakata..:

通过完全精确,我假设足够的精度来显示预期值的最佳近似值,但应该指出double使用基数2表示存储,而基数2不能表示精确到达的东西1.1.获得实际双精度(具有NO ROUND OFF ERROR)的全精度的唯一方法是打印出二进制位(或十六进制数).一种方法是double将a 写入a 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;



6> Daniel Laügt..:

以下是如何以完全精度显示双精度:

double d = 100.0000000000005;
int precision = std::numeric_limits::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;

这显示:

100.0000000000005


max_digits10是唯一表示所有不同double值所必需的位数.max_digits10表示小数点前后的位数.


不要将set_precision(max_digits10)与std :: fixed一起使用.
在固定表示法上,set_precision()仅在小数点设置位数.这是不正确的,max_digits10代表位数之前之后的小数点.

double d = 100.0000000000005;
int precision = std::numeric_limits::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;

这显示错误的结果:

100.00000000000049738

注意:需要头文件

#include 
#include 


发生这种情况是因为`100.0000000000005`没有完全表示为'double`.(看起来应该是这样,但事实并非如此,因为它得到了[规范化](https://en.wikipedia.org/wiki/IEEE_754-1985),即它的二进制表示.要看到这个,请尝试:`100.0000000000005 - 100`.我们得到`4.973799150320701e-13`.

7> chux - Reins..:

如何double使用cout以全精度打印值?

使用hexfloat
使用scientific并设置精度

std::cout.precision(std::numeric_limits::max_digits10 - 1);
std::cout << std::scientific <<  1.0/7.0 << '\n';

// C++11 Typical output
1.4285714285714285e-01

答案太多,只能解决1)基本2)固定/科学布局或3)精度之一。太多的精确答案无法提供所需的正确值。因此,这个答案是一个古老的问题。

    什么基础?

A double当然是使用base 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

    否则:fixedscientific

A double浮点类型,不是固定点

请勿使用,否则std::fixed将无法打印double出任何内容0.000...000。对于large 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

    多少精度(多少位数)?

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 * 2 53不同double

然而,如果在与十进制代码打印N显著数字,)的组合[1.0的数量... 10.0是9/10 * 10 Ñ

无论N选择什么(精度)double,十进制文本之间都不会存在一对一的映射。 如果N选择一个固定值,则有时它会比某些double值的实际需要略多或少。我们可能会在(a)少于)(太少)或()太多的错误上错误b)

3名候选人N

a)N从文本文本double转换时,使用so可以使所有文本都到达相同的文本double

std::cout << dbl::digits10 << '\n';
// Typical output
15

b)Ndouble-text- 转换时,请使用so,因此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)或确切的值doubleN == 1000-ish在的情况下denorm_min)。然而,由于这是“工作”,而不是OP的目标,因此将其搁置一旁。


通常是b)用于“ 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
//1234567890123456  17 total digits

相似的C问题

推荐阅读
手机用户2402852307
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有