If in doubt, read the spec. The C++ standard says that digits10
is:
Number of base 10 digits that can be represented without change.
That's a little vague; fortunately, there's a footnote:
Equivalent to FLT_DIG, DBL_DIG, LDBL_DIG
Those are defined in the C standard; let's look it up there:
number of decimal digits, q, such that any floating-point number with q decimal digits can be rounded into a floating-point number with p radix b digits and back again without change to the q decimal digits.
So std::numeric_limits<float>::digits10
is the number of decimal digits such that any floating-point number with that many digits is unchanged if you convert it to a float
and back to decimal.
As you say, floats have about 7 digits of decimal precision, but the error in representation of both fixed-width decimals and floats is not uniformly logarithmic. The relative error in rounding a number of the form 1.xxx.. to a fixed number of decimal places is nearly ten times larger than the relative error of rounding 9.xxx.. to the same number of decimal places. Similarly, depending on where a value falls in a binade, the relative error in rounding it to 24 binary digits can vary by a factor of nearly two.
The upshot of this is that not all seven-digit decimals survive the round trip to float and back, but all six digit decimals do. Hence, std::numeric_limits<float>::digits10
is 6.
There are not that many six and seven digit decimals with exponents in a valid range for the float
type; you can pretty easily write a program to exhaustively test all of them if you're still not convinced.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…