Answers:
您可以直接设置精度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;
cout.precision(numeric_limits<double>::digits10 + 2);
我只得到16 ....
max_digits10
来表示相同的含义。修正了答案以反映这一点。
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
std::setprecision (17)
双重的,请参阅有关@Bill The Lizard答案的评论。
这是我会用的:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
基本上,limits包具有所有内置类型的特征。
浮点数字(浮点/双精度/长双精度)的特征之一是digits10属性。这定义了以10为底的浮点数的精度(我忘记了确切的术语)。
请参阅:http : //www.cplusplus.com/reference/std/limits/numeric_limits.html
有关其他属性的详细信息。
std::setprecision()
: #include <iomanip>
std::numeric_limits<double>
代替numberic_limits<double>
1
到std::numeric_limits<double>::digits10
?
max_digits10
,不是任意的digits10+2
。否则,在的情况下float
,long double
,boost::multiprecision::float128
这将失败,因为你需要+3
,而不是+2
。
iostreams方法有点笨拙。我更喜欢使用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;
输出:
Pi:3.14159265358979
以全精度,我假设平均精度足以显示与预期值的最佳近似值,但是应该指出的double
是,使用基数2表示存储并且基数2不能1.1
精确表示。获得全满的唯一方法实际双精度精度(不带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<double>::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<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;
这将显示错误的结果:
100.00000000000049738
注意:需要头文件
#include <iomanip>
#include <limits>
100.0000000000005
未完全以表示double
。(看起来好像应该,但是没有,因为它已经标准化,即其二进制表示形式)。要查看此内容,请尝试:100.0000000000005 - 100
。我们得到4.973799150320701e-13
。
如何
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
当然是使用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
precision()
设置了科学模式的小数位数。如果不指定scientific
,它将设置位数(不包括指数)。您可能仍然会根据数字值获得科学的输出结果,但是随后您获得的数字也可能少于指定的数字。示例:的cout.precision(3); cout << 1.7976931348623158e+308; // "1.8e+308"
结果printf
可能不同。令人困惑的东西应该引起注意。
char buf[DBL_DECIMAL_DIG + 3 + 5]; sprintf(buf, "%.*g", DBL_DECIMAL_DIG, d);
额外的字符用于:符号,小数点,尾随零,e [+ |-],指数的3位数字( DBL_MAX_10_EXP = 308)。因此所需的字符的总数目是25。
使用ostream :: precision(int)
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
将产生
3.141592653589793, 2.718281828459045
为什么您必须说“ +1”我不知道,但是您从中得到的多余数字是正确的。
这将显示该点后最多两位小数的值。
#include <iostream>
#include <iomanip>
double d = 2.0;
int n = 2;
cout << fixed << setprecison(n) << d;
参见此处: 定点表示法
使用固定浮点表示法将str流的floatfield格式标志设置为固定。
当floatfield设置为固定值时,将使用定点符号写入浮点值:该值用精确字段(precision)指定的小数部分中的位数完全相同,而没有指数部分。
设置小数精度设置用于格式化输出操作上的浮点值的小数精度。
如果您熟悉用于表示浮点的IEEE标准,那么您将知道不可能以全精度显示浮点而不超出该标准的范围,也就是说,它将始终导致实际价值的取整。
您需要首先检查该值是否在范围内,如果是,则使用:
cout << defaultfloat << d ;
使用默认浮点表示法将str流的floatfield格式标志设置为defaultfloat。
当floatfield设置为defaultfloat时,将使用默认表示法写入浮点值:该表示使用所需的尽可能多的有效数字,直到流的小数精度(精度),同时对小数点前后的数字进行计数(如果有) )。
这也是的默认行为cout
,这意味着您不会显式使用它。
fixed
?用double h = 6.62606957e-34;
,fixed
给我0.000000000000000
和scientific
输出6.626069570000000e-34
。