max_digits10的目的是什么?它和digits10有什么不同? [英] What is the purpose of max_digits10 and how is it different from digits10?

查看:2452
本文介绍了max_digits10的目的是什么?它和digits10有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很困惑什么 max_digits10 表示。根据其文档,对于所有积分类型,它为0。 max_digits10 的浮点类型的公式看起来类似于 int digits10

解决方案

简单来说,




  • digits10 是保证文本生存的小数位数→float→文本往返。

  • max_digits10 是保证正确浮动→文字→浮动往返所需的小数位数。



两者都有例外,但这些值给出最低保证。请阅读 max_digits10上的原始提案 一个清楚的例子,W. Kahan教授的话和进一步的细节。大多数C ++实现遵循IEEE 754的浮点数据类型。对于IEEE 754 float digits10 6 code> max_digits10 9 ;对于 double ,它是 15 17 。请注意,这两个数字不应与浮点数的实际小数精度相混淆。



示例 digits10



  * 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<< '\\\
';
std :: cout<< '< s2 < '< '\t'<< std :: fixed<< std :: setprecision(27)<< f2<< '\\\
';

列印

 '8.589973e9'8.589974e + 009 
'0.100000001490116119384765625'0.100000001490116119384765625

全部直到第6个 th 有效数字的数字被保留,而第7个 th 数字没有存储第一个数字。然而,第二个的所有27位数幸免; 这个是个例外。



总之, digits10 给出了在给定的 float 中可以计数的有效数字的数字与其创建的十进制形式中的原始实数相同,即数字在转换为 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<< '\\\
';
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<< '\\\
';
f_s_f(f3,6);
f_s_f(f4,6);
std :: cout<< f3<< '\t'<< f4<< '\\\
';

列印

  0x1.92acdap + 1 0x1.92acdcp + 1 
0x1.92acdap + 1 0x1.92acdcp + 1
0x1.92acdap + 1 0x1.92acdap + 1

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

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


I am confused about what max_digits10 represents. According to its documentation, it is 0 for all integral types. The formula for floating-point types for max_digits10 looks similar to int's digits10's.

解决方案

To put it simple,

  • digits10 is the number of decimal digits guaranteed to survive text → float → text round-trip.
  • max_digits10 is the number of decimal digits needed to guarantee correct float → text → float round-trip.

There will be exceptions to both but these values give the minimum guarantee. Read the original proposal on max_digits10 for a clear example, Prof. W. Kahan's words and further details. Most C++ implementations follow IEEE 754 for their floating-point data types. For an IEEE 754 float, digits10 is 6 and max_digits10 is 9; for a double it is 15 and 17. Note that both these numbers should not be confused with the actual decimal precision of floating-point numbers.

Example 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';

Prints

'8.589973e9'      8.589974e+009
'0.100000001490116119384765625'   0.100000001490116119384765625

All digits up to the 6th significant digit were preserved, while the 7th digit didn't survive for the first number. However, all 27 digits of the second survived; this is an exception. However, most numbers become different beyond 7 digits and all numbers would be the same within 6 digits.

In summary, digits10 gives the number of significant digits you can count on in a given float as being the same as the original real number in its decimal form from which it was created i.e. the digits that survived after the conversion into a float.

Example 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';

Prints

0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdap+1

Here two different floats, when printed with max_digits10 digits of precision, they give different strings and these strings when read back would give back the original floats they are from. When printed with lesser precision they give the same output due to rounding and hence when read back lead to the same float, when in reality they are from different values.

In summary, max_digits10 are at least required to disambiguate two floats in their decimal form, so that when converted back to a binary float, we get the original bits again and not of the one slightly before or after it due to rounding errors.

这篇关于max_digits10的目的是什么?它和digits10有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆