だから私は私の最後の質問に対する答えを得ました(なぜ私がそれを考えなかったのか分かりません)。思いがけない丸みを帯びた用法double
を印刷してcout
いた。完全な精度でcout
印刷するにはどうすればよいdouble
ですか?
だから私は私の最後の質問に対する答えを得ました(なぜ私がそれを考えなかったのか分かりません)。思いがけない丸みを帯びた用法double
を印刷してcout
いた。完全な精度でcout
印刷するにはどうすればよいdouble
ですか?
回答:
精度を直接設定してstd::cout
、std::fixed
フォーマット指定子を使用できます。
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
#include <limits>
floatまたはdoubleの最大精度を取得できます。
#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パッケージには、すべての組み込みタイプの特性があります。
浮動小数点数(float / double / long double)の特性の1つは、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
。
iostreamの方法はちょっと不格好です。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
base 2表現を使用して格納され、base 2はそれほど単純なものを表現できないことを指摘する必要があります1.1
。実際のdoubleの完全な精度を取得する唯一の方法(NO ROUND OFF ERRORを使用)は、バイナリビット(または16進ニブル)を出力することです。これを行う1つの方法は、double
を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を表示する方法です。
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は、小数点の前後の桁数を表します。
std :: fixedでset_precision(max_digits10)を使用しないでください。
固定表記上、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)精度のいずれか1つだけに対応します。正確な回答が多すぎると、必要な適切な値が得られません。したがって、これは古い質問に対する答えです。
A double
は確かにbase 2を使用してエンコードされます。C++ 11での直接的なアプローチは、を使用して印刷することstd::hexfloat
です。
10進数以外の出力が許容できる場合は、これで完了です。
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
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
Aは、double
バイナリベース2つのエンコードこれは、多くの場合、53ビットである2の様々なパワーと同じ精度を使用してエンコード。
[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
有効数字の10進数で出力される場合、組み合わせの数[1.0 ... 10.0)は9/10 * 10 Nです。
どのN
(精度)を選択してもdouble
、10進テキストとの間に1対1のマッピングはありません。 固定値N
が選択された場合、特定のdouble
値で実際に必要な値よりもわずかに多いまたは少ない場合があります。エラーが少なすぎる(a)
以下)または多すぎる(以下)可能性がありますb)
。
3候補N
:
a)N
text--textから変換する場合は、soを使用して、double
すべてのテキストが同じになるようにしますdouble
。
std::cout << dbl::digits10 << '\n';
// Typical output
15
B)を使用してN
から変換するときにdouble
-text- 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
十分な10進数が出力されることを保証するために使用できることに注意してください。
c)N
値によって異なるを使用します。
これは、コードが最小限のテキスト(N == 1
)またはa の正確な値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);
は次のとおりです。 DBL_MAX_10_EXP = 308)。したがって必要な文字の総数は25である
printf("%.12f", M_PI);
%.12fは浮動小数点を意味し、精度は12桁です。
最も移植性の高い...
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;
ostream :: precision(int)を使用
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
譲ります
3.141592653589793, 2.718281828459045
なぜ「+1」と言わなければならないのか、私には手掛かりがありませんが、それから得られる余分な数字は正しいです。
これにより、ドットの後に小数点以下2桁までの値が表示されます。
#include <iostream>
#include <iomanip>
double d = 2.0;
int n = 2;
cout << fixed << setprecison(n) << d;
こちらをご覧ください: 固定小数点表記
固定浮動小数点表記を使用strストリームの浮動フィールド形式フラグを固定に設定します。
floatfieldがfixedに設定されている場合、浮動小数点値は固定小数点表記を使用して書き込まれます。値は、精度フィールド(精度)で指定された小数部の桁数とまったく同じで、指数部はありません。
小数精度の設定出力操作で浮動小数点値をフォーマットするために使用される小数精度を設定します。
浮動小数点を表すためのIEEE標準に精通している場合は、標準の範囲外で完全精度で浮動小数点を表示することは不可能であることがわかります。つまり、常に実際の値の丸め。
最初に値がスコープ内にあるかどうかを確認する必要があります。ある場合は、次を使用します。
cout << defaultfloat << d ;
デフォルトの浮動小数点表記を使用strストリームのfloatfield形式フラグをdefaultfloatに設定します。
floatfieldがdefaultfloatに設定されている場合、浮動小数点値はデフォルト表記法を使用して書き込まれます。表現は、ストリームの小数精度(精度)まで必要なだけ有効な数字を使用し、小数点の前後の両方の数字(存在する場合)をカウントします)。
これはのデフォルトの動作でもあります。つまりcout
、明示的には使用しません。
fixed
ですか?でdouble h = 6.62606957e-34;
、fixed
私0.000000000000000
とscientific
出力を提供します6.626069570000000e-34
。