max_digits10的目的是什么?它与digits10的不同之处是什么?

NoS*_*tAl 11 c++ precision numeric-limits floating-point-precision c++11

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

Cub*_*bbi 24

简单来说,

  • digits10 是保证生存的十进制数字的数字→浮动→文本往返.
  • max_digits10 是保证正确浮动→文本→浮动往返所需的小数位数.

两者都有例外,但这些值给出了最低限度的保证.阅读原始提案,max_digits10以获得一个明确的例子,W.Kahan教授的话和进一步的细节.大多数C++实现都遵循IEEE 754的浮点数据类型.对于IEEE 754 float,digits106max_digits109; 因为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';
Run Code Online (Sandbox Code Playgroud)

打印

'8.589973e9'      8.589974e+009
'0.100000001490116119384765625'   0.100000001490116119384765625
Run Code Online (Sandbox Code Playgroud)

保留了第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';
Run Code Online (Sandbox Code Playgroud)

打印

0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdap+1
Run Code Online (Sandbox Code Playgroud)

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

总之,max_digits10至少需要消除十进制形式的两个浮点数的歧义,这样当转换回二进制浮点数时,由于舍入误差,我们再次获得原始位而不是之前或之后的位.


dev*_*fan 2

在我看来,链接站点(以及digits10的站点)对此进行了充分的解释:

\n\n

digits10 是“十进制”数字的(最大)数量,其中数字
在任何情况下都可以由类型表示,而与其实际值无关。
\n以常见的 4 字节无符号整数为例:众所周知,它正好有 32 位,
\n即 32 位二进制数。
\n但就十进制数而言?
\n可能是9。
\n因为它可以存储100000000,也可以存储999999999。
\n但是如果取10位数字:可以存储4000000000,但不能存储5000000000。
\n因此,如果我们需要保证最小十进制数字容量,则为 9。
\n这就是digits10 的结果。

\n\n


max_digits10 仅对 float/double 感兴趣...并给出我们需要输出/保存/处理的小数位数...以获取
浮点类型可以提供的整个精度。
\n理论示例:内容为 123.112233445566 的变量
\n如果向用户显示 123.11223344,则它并不那么精确。
\n如果您向用户显示 123.1122334455660000000,则没有任何意义,因为
\n您可以省略尾随零(因为您的变量无论如何都可以 \xc2\xb4t 保存那么多)
\n因此,max_digits10 表示类型中可用的位数精度。

\n