C++ max_digits10的目的是什么?它与digits10有何不同?

C++ max_digits10的目的是什么?它与digits10有何不同?,c++,c++11,precision,floating-point-precision,numeric-limits,C++,C++11,Precision,Floating Point Precision,Numeric Limits,我不知道max_Digits 10所代表的是什么。根据,对于所有整数类型,它都是0。max_digits10的浮点类型公式看起来类似于int的digits10。在我看来,链接站点(以及digits10站点)对其进行了充分解释: digits10是数字 在任何情况下都可以用类型表示,与它们的实际值无关。 举一个常见的4字节无符号整数为例:众所周知,它正好有32位, 这是一个二进制数的32位。 但是用十进制数来表示吗? 可能是9。 因为,它可以存储100000000以及99999999。 但如果使用

我不知道max_Digits 10所代表的是什么。根据,对于所有整数类型,它都是0。
max_digits10
的浮点类型公式看起来类似于
int
digits10

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

digits10是数字
在任何情况下都可以用类型表示,与它们的实际值无关。
举一个常见的4字节无符号整数为例:众所周知,它正好有32位,
这是一个二进制数的32位。
但是用十进制数来表示吗?
可能是9。
因为,它可以存储100000000以及99999999。
但如果使用10位数的数字:可以存储4000000000,但不能存储5000000000。
因此,如果我们需要最小十进制数字容量的保证,它是9。
这就是digits10的结果

max_digits10仅对浮点/双精度。。。并给出十进制数字计数
我们需要输出/保存/处理。。。以获取整个精度
浮点类型可以提供。
理论示例:内容为123.112233445566的变量
如果您向用户显示123.11223344,则该值可能不够精确。
如果向用户显示123.11223344556600000,则没有意义,因为
您可以省略尾随的零(因为您的变量无论如何不能容纳那么多)
因此,max_digits10表示一种类型中可用的数字精度。

简单地说

  • digits10
    是保证在文本中保留的小数位数→ 浮动→ 文本往返
  • max_digits10
    是保证正确浮点数所需的十进制位数→ 正文→ 浮动往返
两者都有例外,但这些值提供了最低限度的保证。阅读《max_digits10》上的文章,了解一个清晰的例子,W.Kahan教授的话和更多细节。大多数C++实现遵循IEEE 754的浮点数据类型。对于IEEE 754
float
digits10
6
max_digits10
9
;对于
double
而言,它是
15
17
。请注意,这两个数字都具有浮点数字的实际十进制精度

示例
digits10
第6位有效数字之前的所有数字均被保留,而第7位数字在第一个数字中无法保留。然而,第二个的27个数字全部存活;这是个例外。然而,大多数数字在超过7位之后会变得不同,而所有数字在6位之内都是相同的

总之,
digits10
给出了在给定的
float
中可以计算的有效位数,与创建它的原始十进制实数相同,即转换为
float
后保留的位数

示例
max\u digits10
这里有两个不同的
float
s,当使用
max_digits 10
精度数字打印时,它们给出不同的字符串,这些字符串在读回时将返回它们原来的
float
s。当打印精度较低时,由于四舍五入,它们会给出相同的输出,因此当读回时会导致相同的
浮点值
,而实际上它们来自不同的值


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

您使用十进制数字作为:“base10位”或“右位”@有效位中以10位数字为底。在digits10示例中:
8.589973e9
有7位十进制数字,不能在文本->浮点->文本往返中生存。@legends2k如果您想调用某人的代码UB,最好先了解链接到的答案。不是所有的
oss.str().c_str()
都是UB,而且原始代码写得很好。好吧,我可能错了。但是我想学习,请告诉我返回的临时字符串如何超越表达式?什么
c_str
现在不是指向一个解构的
string
对象吗?@legends2k它只在创建它的完整表达式中使用。销毁任何临时文件后,不会执行对strof的调用。相关:
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
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