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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:56:02  来源:igfitidea点击:

How do I print a double value with full precision using cout?

c++floating-pointprecisioniostreamcout

提问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 doubleusing coutthat got rounded when I wasn't expecting it. How can I make coutprint a doubleusing full precision?

所以我得到了我最后一个问题的答案(我不知道为什么我没有想到这一点)。当我没想到它时,我正在打印一个四舍五入的double使用cout。如何使用全精度进行cout打印double

回答by Bill the Lizard

You can set the precision directly on std::coutand use the std::fixedformat 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::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_castbecause 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 doubleis stored using base 2 representation and base 2 can't represent something as trivial as 1.1exactly. 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 doubleto a unionand 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 doublevalue with full precision using cout?

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

Use hexfloator
use scientificand 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) 精度之一。太多精确的答案无法提供所需的正确值。因此,这是对一个老问题的回答。

  1. What base?
  1. 什么基地?

A doubleis 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


  1. Otherwise: fixedor scientific?
  1. 否则:fixedscientific?

A doubleis a floating pointtype, not fixed point.

Adouble浮点类型,而不是固定点

Do notuse std::fixedas that fails to print small doubleas 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::scientificwhich 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::scientificwhich 将“以科学记数法写入浮点值”。注意默认小数点后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


  1. How much precision (how many total digits)?
  1. 多少精度(多少总位数)?

A doubleencoded 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 Nsignificant 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 doubleand decimal text.If a fixed Nis chosen, sometimes it will be slightly more or less than truly needed for certain doublevalues. 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 Nso when converting from text-double-text we arrive at the same text for all double.

a)N在从doubletext--text 转换时使用so ,我们为所有double.

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

b) Use an Nso when converting from double-text-doublewe arrive at the same doublefor all double.

b)Ndouble-text-转换时使用so ,double我们double对所有double.

// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17

When max_digits10is not available, note that due to base 2 and base 10 attributes, digits10 + 2 <= max_digits10 <= digits10 + 3, we can use digits10 + 3to insure enough decimal digits are printed.

max_digits10不可用时,请注意,由于 base 2 和 base 10 属性digits10 + 2 <= max_digits10 <= digits10 + 3,我们可以使用digits10 + 3来确保打印足够的十进制数字。

c) Use an Nthat 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-ishin the case of denorm_min). Yet since this is "work" and not likely OP's goal, it will be set aside.

当代码想要显示最少的文本 ( N == 1) 或 a 的确切doubleN == 1000-ish在 的情况下denorm_min)时,这会很有用。然而,由于这是“工作”并且不太可能是 OP 的目标,因此它将被搁置一旁。



It is usually b) that is used to "print a doublevalue 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_digits10total 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

Similar C question

类似的 C 问题

回答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

请参阅此处:定点表示法

std::fixed

标准::固定

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 时,浮点值使用定点表示法写入:该值用精度字段(精度)指定的小数部分中的位数表示,没有指数部分。

std::setprecision

标准::设置精度

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 ;

std::defaultfloat

标准::默认浮动

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,这意味着您没有明确使用它。