所以我已经得到了我最后一个问题的答案(我不知道为什么我没有想到这一点).当我没想到它的时候,我正在打印一个圆润的double
使用cout
.如何使用全精度cout
打印double
?
您可以直接设置精度std::cout
并使用std::fixed
格式说明符.
double d = 3.14159265358979; cout.precision(17); cout << "Pi: " << fixed << d << endl;
您#include
可以获得浮点数或双精度的最大精度.
#includetypedef 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::digits10 + 1) << 3.14159265358979 << std::endl;
基本上,限制包具有所有类型的内置特征.
浮点数(float/double/long double)的特征之一是digits10属性.这定义了基数10中浮点数的准确性(我忘记了确切的术语).
请参阅:http://www.cplusplus.com/reference/std/limits/numeric_limits.html
有关其他属性的详细信息.
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
通过完全精确,我假设足够的精度来显示预期值的最佳近似值,但应该指出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;
以下是如何以完全精度显示双精度:
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
如何
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
否则:fixed
或scientific
?
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)N
从double
-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
)或确切的值double
(N == 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问题