何max_digits10
を表しているのか迷っています。そのドキュメントによると、すべての整数型で 0 です。の浮動小数点型の式は、 の式に似max_digits10
ています。int
digits10
2 に答える
簡単に言えば、
digits10
テキスト → 浮動小数点 → テキストのラウンドトリップに耐えることが保証されている 10 進数の桁数です。max_digits10
float → text → float の正しい往復を保証するために必要な 10 進数の桁数です。
どちらにも例外はありますが、これらの値は最低限の保証を提供します。明確な例、W. Kahan 教授の言葉、および詳細については、元の提案をお読みください。max_digits10
ほとんどの C++ 実装は、浮動小数点データ型について IEEE 754 に従います。IEEE 754float
の場合、digits10
is6
およびmax_digits10
is 9
; とdouble
です。_ これらの数値を、浮動小数点数の実際の 10 進精度と混同しないでください。15
17
例digits10
char const *s1 = "8.589973e9";
char const *s2 = "0.100000001490116119384765625";
float const f1 = strtof(s1, nullptr);
float const f2 = strtof(s2, nullptr);
std::cout << "'" << s1 << "'" << '\t' << std::scientific << f1 << '\n';
std::cout << "'" << s2 << "'" << '\t' << std::fixed << std::setprecision(27) << f2 << '\n';
版画
'8.589973e9' 8.589974e+009
'0.100000001490116119384765625' 0.100000001490116119384765625
有効数字の 6 桁目までのすべての数字は保持されましたが、7桁目は最初の数字として存続しませんでした。ただし、秒の 27 桁はすべて残っていました。これは例外です。ただし、ほとんどの数字は 7 桁を超えると異なり、6 桁以内ではすべての数字が同じになります。
要約すると、digits10
与えられた で期待できる有効桁数をfloat
、作成元の 10 進形式の元の実数と同じであると見なすことができます。つまり、 への変換後に残った桁数ですfloat
。
例max_digits10
void f_s_f(float &f, int p) {
std::ostringstream oss;
oss << std::fixed << std::setprecision(p) << f;
f = strtof(oss.str().c_str(), nullptr);
}
float f3 = 3.145900f;
float f4 = std::nextafter(f3, 3.2f);
std::cout << std::hexfloat << std::showbase << f3 << '\t' << f4 << '\n';
f_s_f(f3, std::numeric_limits<float>::max_digits10);
f_s_f(f4, std::numeric_limits<float>::max_digits10);
std::cout << f3 << '\t' << f4 << '\n';
f_s_f(f3, 6);
f_s_f(f4, 6);
std::cout << f3 << '\t' << f4 << '\n';
版画
0x1.92acdap+1 0x1.92acdcp+1
0x1.92acdap+1 0x1.92acdcp+1
0x1.92acdap+1 0x1.92acdap+1
ここで 2 つの異なるfloat
s は、max_digits10
桁数の精度で出力されると異なる文字列になり、これらの文字列を読み返すと元float
の s が返されます。float
より低い精度で印刷すると、丸めのために同じ出力が得られるため、実際には異なる値からのものであっても、読み返すと同じになります。
要約max_digits10
すると、少なくとも 2 つの浮動小数点数を 10 進形式で明確にする必要があります。これにより、2 進浮動小数点数に変換されたときに、丸め誤差のためにわずかに前後のビットではなく、元のビットが再び取得されます。