Jas*_*yon 308 c++ floating-point precision iostream cout
所以我已经得到了我最后一个问题的答案(我不知道为什么我没有想到这一点).当我没想到它的时候,我正在打印一个圆润的double使用cout.如何使用全精度cout打印double?
Bil*_*ard 369
您可以直接设置精度std::cout并使用std::fixed格式说明符.
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
Run Code Online (Sandbox Code Playgroud)
您#include <limits>可以获得浮点数或双精度的最大精度.
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
Run Code Online (Sandbox Code Playgroud)
Pau*_*ham 65
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
Run Code Online (Sandbox Code Playgroud)
Mar*_*ork 23
这是我会用的:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
Run Code Online (Sandbox Code Playgroud)
基本上,限制包具有所有类型的内置特征.
浮点数(float/double/long double)的特征之一是digits10属性.这定义了基数10中浮点数的准确性(我忘记了确切的术语).
请参阅:http://www.cplusplus.com/reference/std/limits/numeric_limits.html
有关其他属性的详细信息.
Tim*_*003 13
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;
Run Code Online (Sandbox Code Playgroud)
输出:
Pi:3.14159265358979
vit*_*aut 11
在 C++20 中,您将能够使用它std::format来执行此操作:
std::cout << std::format("{}", M_PI);
Run Code Online (Sandbox Code Playgroud)
输出(假设 IEEE754 double):
std::cout << std::format("{}", M_PI);
Run Code Online (Sandbox Code Playgroud)
默认浮点格式是具有往返保证的最短十进制表示。与setprecisionI/O 操纵器相比,这种方法的优势在于它不会打印不必要的数字。
在此期间,您可以使用的{} FMT库,std::format是基于。{fmt} 还提供了print使这更容易和更高效的功能(Godbolt):
fmt::print("{}", M_PI);
Run Code Online (Sandbox Code Playgroud)
免责声明:我是 {fmt} 和 C++20 的作者std::format。
Mar*_*ata 10
通过完全精确,我假设足够的精度来显示预期值的最佳近似值,但应该指出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;
Run Code Online (Sandbox Code Playgroud)
这将为您提供100%准确的双精度...并且完全不可读,因为人类无法读取IEEE双格式! 维基百科对如何解释二进制位有很好的写作.
在较新的C++中,你可以做到
std::cout << std::hexfloat << 1.1;
Run Code Online (Sandbox Code Playgroud)
Dan*_*ügt 10
以下是如何以完全精度显示双精度:
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
Run Code Online (Sandbox Code Playgroud)
这显示:
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;
Run Code Online (Sandbox Code Playgroud)
这显示错误的结果:
100.00000000000049738
注意:需要头文件
#include <iomanip>
#include <limits>
Run Code Online (Sandbox Code Playgroud)
如何
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
Run Code Online (Sandbox Code Playgroud)
答案太多,只能解决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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
要以全精度打印,请先使用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
Run Code Online (Sandbox Code Playgroud)
甲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
Run Code Online (Sandbox Code Playgroud)
b)N从double-text- 转换时,请使用so,因此double我们double对所有都得出相同的结果double。
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
Run Code Online (Sandbox Code Playgroud)
当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
Run Code Online (Sandbox Code Playgroud)
C++20 std::format
This great new C++ library feature has the advantage of not affecting the state of std::cout as std::setprecision does:
#include <format>
#include <string>
int main() {
std::cout << std::format("{:.2} {:.3}\n", 3.1415, 3.1415);
}
Run Code Online (Sandbox Code Playgroud)
Expected output:
3.14 3.142
Run Code Online (Sandbox Code Playgroud)
正如/sf/answers/4573086241/中提到的,如果您没有明确传递精度,它会打印带有往返保证的最短十进制表示形式。TODO 更详细地了解它与以下内容的比较:如/sf/answers/38789411/dbl::max_digits10所示:{:.{}}
#include <format>
#include <limits>
#include <string>
int main() {
std::cout << std::format("{:.{}}\n",
3.1415926535897932384626433, dbl::max_digits10);
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
413648 次 |
| 最近记录: |