C++ 如何使用 cout 以全精度打印双精度值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/554063/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I print a double value with full precision using cout?
提问by Jason Punyon
So I've gotten the answer to my last question(I don't know why I didn't think of that). I was printing a double
using cout
that got rounded when I wasn't expecting it. How can I make cout
print a double
using full precision?
所以我得到了我最后一个问题的答案(我不知道为什么我没有想到这一点)。当我没想到它时,我正在打印一个四舍五入的double
使用cout
。如何使用全精度进行cout
打印double
?
回答by Bill the Lizard
You can set the precision directly on std::cout
and use the std::fixed
format specifier.
您可以直接设置精度std::cout
并使用std::fixed
格式说明符。
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
You can #include <limits>
to get the maximum precision of a float or double.
您#include <limits>
可以获得浮点数或双精度数的最大精度。
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
回答by Paul Beckingham
Use std::setprecision
:
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
回答by Martin York
Here is what I would use:
这是我会使用的:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
Basically the limits package has traits for all the build in types.
One of the traits for floating point numbers (float/double/long double) is the digits10 attribute. This defines the accuracy (I forget the exact terminology) of a floating point number in base 10.
基本上,limits 包具有所有构建类型的特征。
浮点数(float/double/long double)的特征之一是digits10 属性。这定义了基数为 10 的浮点数的准确性(我忘记了确切的术语)。
See: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
For details about other attributes.
有关其他属性的详细信息,请参见:http: //www.cplusplus.com/reference/std/limits/numeric_limits.html
。
回答by Timothy003
The iostreams way is kind of clunky. I prefer using boost::lexical_cast
because it calculates the right precision for me. And it's fast, too.
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;
Output:
输出:
Pi: 3.14159265358979
圆周率:3.14159265358979
回答by Mark Lakata
By full precision, I assume mean enough precision to show the best approximation to the intended value, but it should be pointed out that double
is stored using base 2 representation and base 2 can't represent something as trivial as 1.1
exactly. The only way to get the full-fullprecision of the actual double (with NO ROUND OFF ERROR) is to print out the binary bits (or hex nybbles). One way of doing that is writing the double
to a union
and then printing out the integer value of the bits.
通过完全精度,我假设有足够的精度来显示对预期值的最佳近似值,但应该指出的double
是,使用基数 2 表示存储,基数 2 不能1.1
精确地表示一些微不足道的东西。获得实际双精度的全精度(没有 ROUND OFF 错误)的唯一方法是打印出二进制位(或十六进制 nybbles)。一种方法是double
将 a写入a union
,然后打印出这些位的整数值。
union {
double d;
uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;
This will give you the 100% accurate precision of the double... and be utterly unreadable because humans can't read IEEE double format ! Wikipediahas a good write up on how to interpret the binary bits.
这将为您提供 double 的 100% 准确精度......并且完全不可读,因为人类无法阅读 IEEE double 格式! 维基百科有一篇关于如何解释二进制位的好文章。
In newer C++, you can do
在较新的 C++ 中,你可以这样做
std::cout << std::hexfloat << 1.1;
回答by Daniel Laügt
Here is how to display a double with full precision:
以下是如何以全精度显示双精度:
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
This displays:
这显示:
100.0000000000005
100.0000000000005
max_digits10 is the number of digits that are necessary to uniquely represent all distinct double values. max_digits10 represents the number of digits before and after the decimal point.
max_digits10 是唯一表示所有不同双精度值所需的位数。max_digits10 表示小数点前后的位数。
Don't use set_precision(max_digits10) with std::fixed.
On fixed notation, set_precision() sets the number of digits only afterthe decimal point. This is incorrect as max_digits10 represents the number of digits beforeand afterthe decimal point.
不要将 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;
This displays incorrect result:
这显示不正确的结果:
100.00000000000049738
100.00000000000049738
Note: Header files required
注意:需要头文件
#include <iomanip>
#include <limits>
回答by chux - Reinstate Monica
How do I print a
double
value with full precision using cout?
如何
double
使用 cout 以全精度打印值?
Use hexfloat
or
use scientific
and set the precision
使用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
Too many answers address only one of 1) base 2) fixed/scientific layout or 3) precision. Too many answers with precisiondo not provide the proper value needed. Hence this answer to a old question.
太多答案仅针对 1) 基础 2) 固定/科学布局或 3) 精度之一。太多精确的答案无法提供所需的正确值。因此,这是对一个老问题的回答。
- What base?
- 什么基地?
A double
is certainly encoded using base 2. A direct approach with C++11 is to print using std::hexfloat
.
If a non-decimal output is acceptable, we are done.
Adouble
肯定是使用基数 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
- Otherwise:
fixed
orscientific
?
- 否则:
fixed
或scientific
?
A double
is a floating pointtype, not fixed point.
Adouble
是浮点类型,而不是固定点。
Do notuse std::fixed
as that fails to print small double
as anything but 0.000...000
. For large double
, it prints many digits, perhaps hundredsof questionable informativeness.
千万不能使用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
To print with full precision, first use std::scientific
which will "write floating-point values in scientific notation". Notice the default of 6 digits after the decimal point, an insufficient amount, is handled in the next point.
要以全精度打印,首先使用std::scientific
which 将“以科学记数法写入浮点值”。注意默认小数点后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
- How much precision (how many total digits)?
- 多少精度(多少总位数)?
A double
encoded using the binary base 2 encodes the same precision between various powers of 2. This is often 53 bits.
甲double
使用二进制基座2个编码各种权力的2.这通常是53个比特之间的相同的精度进行编码。
[1.0...2.0) there are 253different double
,
[2.0...4.0) there are 253different double
,
[4.0...8.0) there are 253different double
,
[8.0...10.0) there are 2/8 * 253different double
.
[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
。
Yet if code prints in decimal with N
significant digits, the number of combinations [1.0...10.0) is 9/10 * 10N.
然而,如果代码以N
有效数字以十进制打印,则组合数 [1.0...10.0) 为 9/10 * 10 N。
Whatever N
(precision) is chosen, there will not be a one-to-one mapping between double
and decimal text.If a fixed N
is chosen, sometimes it will be slightly more or less than truly needed for certain double
values. We could error on too few (a)
below) or too many (b)
below).
无论N
选择什么(精度),都不会在double
和十进制文本之间存在一对一的映射。如果N
选择了固定值,有时它会比某些double
值真正需要的略多或略少。我们可能会在太少(a)
下)或太多(b)
下)上出错。
3 candidate N
:
3 候选人N
:
a) Use an N
so when converting from text-double
-text we arrive at the same text for all double
.
a)N
在从double
text--text 转换时使用so ,我们为所有double
.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) Use an N
so when converting from double
-text-double
we arrive at the same double
for all double
.
b)N
从double
-text-转换时使用so ,double
我们double
对所有double
.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
When max_digits10
is not available, note that due to base 2 and base 10 attributes, digits10 + 2 <= max_digits10 <= digits10 + 3
, we can use digits10 + 3
to insure enough decimal digits are printed.
当max_digits10
不可用时,请注意,由于 base 2 和 base 10 属性digits10 + 2 <= max_digits10 <= digits10 + 3
,我们可以使用digits10 + 3
来确保打印足够的十进制数字。
c) Use an N
that varies with the value.
c) 使用N
随值变化的 。
This can be useful when code wants to display minimal text (N == 1
) or the exactvalue of a double
(N == 1000-ish
in the case of denorm_min
). Yet since this is "work" and not likely OP's goal, it will be set aside.
当代码想要显示最少的文本 ( N == 1
) 或 a 的确切值double
(N == 1000-ish
在 的情况下denorm_min
)时,这会很有用。然而,由于这是“工作”并且不太可能是 OP 的目标,因此它将被搁置一旁。
It is usually b) that is used to "print a double
value with full precision". Some applications may prefer a) to error on not providing too much information.
通常 b) 用于“double
以全精度打印值”。一些应用程序可能更喜欢 a) 在不提供太多信息时出错。
With .scientific
, .precision()
sets the number of digits to print after the decimal point, so 1 + .precision()
digits are printed. Code needs max_digits10
total digits so .precision()
is called with a max_digits10 - 1
.
使用.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
回答by Maister
printf("%.12f", M_PI);
%.12f means floating point, with precision of 12 digits.
%.12f 表示浮点数,精度为 12 位。
回答by Jann
With ostream::precision(int)
使用 ostream::precision(int)
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
will yield
会屈服
3.141592653589793, 2.718281828459045
Why you have to say "+1" I have no clue, but the extra digit you get out of it is correct.
为什么你必须说“+1”我不知道,但你从中得到的额外数字是正确的。
回答by emmmphd
This will show the value up to two decimal places after the dot.
这将显示点后最多两位小数的值。
#include <iostream>
#include <iomanip>
double d = 2.0;
int n = 2;
cout << fixed << setprecison(n) << d;
See here:Fixed-point notation
请参阅此处:定点表示法
Use fixed floating-point notation Sets the floatfield format flag for the str stream to fixed.
When floatfield is set to fixed, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision) and with no exponent part.
使用固定浮点表示法将 str 流的浮点格式标志设置为固定。
当 floatfield 设置为 fixed 时,浮点值使用定点表示法写入:该值用精度字段(精度)指定的小数部分中的位数表示,没有指数部分。
Set decimal precision Sets the decimal precision to be used to format floating-point values on output operations.
设置小数精度 设置用于格式化输出操作中的浮点值的小数精度。
If you're familiar with the IEEE standard for representing the floating-points, you would know that it is impossible to show floating-points with full-precision out of the scope of the standard, that is to say, it will always result in a rounding of the real value.
如果您熟悉表示浮点数的 IEEE 标准,您就会知道不可能在标准范围之外以全精度显示浮点数,也就是说,它总是会导致实际值的四舍五入。
You need to first check whether the value is within the scope, if yes, then use:
您需要先检查该值是否在范围内,如果是,则使用:
cout << defaultfloat << d ;
Use default floating-point notation Sets the floatfield format flag for the str stream to defaultfloat.
When floatfield is set to defaultfloat, floating-point values are written using the default notation: the representation uses as many meaningful digits as needed up to the stream's decimal precision (precision), counting both the digits before and after the decimal point (if any).
使用默认浮点符号将 str 流的 floatfield 格式标志设置为 defaultfloat。
当 floatfield 设置为 defaultfloat 时,使用默认表示法写入浮点值:表示使用尽可能多的有意义的数字,直到流的小数精度(精度),计算小数点前后的数字(如果有的话) )。
That is also the default behavior of cout
, which means you don't use it explicitly.
这也是 的默认行为cout
,这意味着您没有明确使用它。