15

我对代表什么感到困惑max_digits10。根据其文档,对于所有整数类型,它都是 0。浮点类型的公式max_digits10看起来类似于int' digits10s 。

4

2 回答 2

28

简单来说,

  • digits10是保证文本→浮点→文本往返的十进制位数。
  • max_digits10是保证正确浮点→文本→浮点往返所需的小数位数。

两者都有例外,但这些值提供了最低限度的保证。阅读原始提案max_digits10获取明确的示例、W. Kahan 教授的话和更多细节。大多数 C++ 实现的浮点数据类型都遵循 IEEE 754。对于 IEEE 754 floatdigits10is6max_digits10is 9;因为double它是1517。请注意,这两个数字不应与浮点数的实际十进制精度相混淆。

例子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创建它的十进制形式的原始实数相同,即转换为 a 后幸存的数字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

这里有两个不同float的 s,当以精度数字打印时max_digits10,它们会给出不同的字符串,而这些字符串在读回时会返回float它们来自的原始 s。当以较低的精度打印时,由于舍入,它们会给出相同的输出,因此当回读时会导致相同的结果float,而实际上它们来自不同的值。

总之,max_digits10至少需要以十进制形式消除两个浮点数的歧义,以便在转换回二进制浮点数时,我们会再次获得原始位,而不是由于舍入错误而稍微之前或之后的位。

于 2014-03-17T15:50:32.297 回答
2

In my opinion, it is explained sufficiently at the linked site (and the site for digits10):

digits10 is the (max.) amount of "decimal" digits where numbers
can be represented by a type in any case, independent of their actual value.
A usual 4-byte unsigned integer as example: As everybody should know, it has exactly 32bit,
that is 32 digits of a binary number.
But in terms of decimal numbers?
Probably 9.
Because, it can store 100000000 as well as 999999999.
But if take numbers with 10 digits: 4000000000 can be stored, but 5000000000 not.
So, if we need a guarantee for minimum decimal digit capacity, it is 9.
And that is the result of digits10.

max_digits10 is only interesting for float/double... and gives the decimal digit count
which we need to output/save/process... to take the whole precision
the floating point type can offer.
Theoretical example: A variable with content 123.112233445566
If you show 123.11223344 to the user, it is not as precise as it can be.
If you show 123.1122334455660000000 to the user, it makes no sense because
you could omit the trailing zeros (because your variable can´t hold that much anyways)
Therefore, max_digits10 says how many digits precision you have available in a type.

于 2014-03-17T15:42:04.893 回答