だから私は私の 最後の質問 に対する答えを得ました(なぜ私はそれを考えなかったのかわかりません)。期待していなかったときに丸められたdouble
を使ってcout
を印刷していました。フル精度でcout
にdouble
を印刷させるにはどうすればよいですか?
精度を直接std::cout
に設定し、 std::fixed
フォーマット指定子を使用することができます。
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
Floatまたはdoubleの最大精度を取得するために#include <limits>
を使用できます。
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
std::setprecision
を使います。
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
これが私が使うものです:
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
他の属性についての詳細.
入出力ストリームの方法は不格好です。私は 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を全精度で表示する方法は次のとおりです。
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>
完全な精度とは、意図した値に最適な近似を示すのに十分な精度を意味すると想定しますが、double
はベース2表現を使用して格納され、ベース2は1.1
正確に。 full-fullの実際のdoubleの精度(ROUND OFF ERRORなし)を取得する唯一の方法は、バイナリビット(または16進ニブル)を出力することです)。これを行う1つの方法は、double
をunion
に書き込んでから、ビットの整数値を出力することです。
union {
double d;
uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;
これにより、doubleの100%正確な精度が得られ、人間がIEEE double形式を読み取れないため、まったく読めなくなります。 Wikipedia には、バイナリビットの解釈方法に関する優れた記事があります。
新しいC++では、次のことができます
std::cout << std::hexfloat << 1.1;
Coutを使用して
double
name__値を全精度で出力するにはどうすればよいですか?
hexfloat
name__を使用するscientific
name__を使用して精度を設定します
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つのみに対処しています。precisionの回答が多すぎると、必要な正しい値が得られません。それ故、これは古い質問に対する答えです。
double
name__は確かに基数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
name__またはscientific
name__?double
name__は浮動小数点型であり、固定小数点ではありません。
not を使用すると、std::fixed
を使用しても、小さいdouble
name__を0.000...000
以外のものとして表示できません。 double
name__が大きい場合、それは多くの数字を出力します。おそらく100/は疑わしい情報です。
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
2進数2を使用してエンコードされたdouble
name__は、さまざまな2の累乗の間で同じ精度をエンコードします。これは通常53ビットです。
[1.0 ... 2.0)2があります53 異なるdouble
name__、
[2.0 ... 4.0)2があります53 異なるdouble
name__、
[4.0 ... 8.0)2があります53 異なるdouble
name__、
[8.0 ... 10.0)2/8 * 2あり53 異なるdouble
name__。
それでも、コードがN
name__の有効数字で10進数で表示される場合、組み合わせの数[1.0 ... 10.0)は9/10 * 10です。N。
どのN
name__(精度)が選択されても、double
name__と10進数テキストの間に1対1のマッピングはありません。 固定のN
name__が選択された場合、時々、それは特定のdouble
name__値のために本当に必要とされるよりわずかに多いかまたは少ないことがあります。エラーが少なすぎる(a)
以下)または多すぎる(b)
以下)場合にエラーが発生する可能性があります。
3人のN
name__の候補者:
a)N
name__を使用すると、text -double
name __- textから変換するときに、すべてのdouble
name__に対して同じテキストが表示されます。
std::cout << dbl::digits10 << '\n';
// Typical output
15
b)N
name__を使用すると、double
name __-text -double
name__から変換するとき、すべてのdouble
name__に対して同じdouble
name__が表示されます。
// 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
name__を使用します。
これは、コードが最小のテキスト(N == 1
)またはexactの値(double
name__)(N == 1000-ish
の場合はdenorm_min
)を表示したい場合に便利です。しかし、これは「仕事」であり、OPの目標ではないと思われるので、それは取っておきます。
通常、b)は「double
name__値を完全精度で印刷する」ために使用されます。いくつかのアプリケーションは、あまりにも多くの情報を提供していないことでエラーを起こすことを好むかもしれません。
.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
printf("%.12f", M_PI);
%12fは、12桁の精度の浮動小数点を意味します。
coutは、印刷物の精度とフォーマットを変更するために呼び出すことができる一連のメソッドを持つオブジェクトです。
Setprecision(...)操作がありますが、印刷幅などの他のものも設定できます。
IDEのリファレンスでcoutを調べてください。
Ostream :: precision(int)を使って
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
収まる
3.141592653589793, 2.718281828459045
なぜあなたは "+1"と言わなければならない私は手がかりを持っていないが、あなたがそれから出る余分な数字は正しいです。
ほとんどのポータブル...
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;