Per Dietmar Kühl’s answer, statements in the C++ standard imply that integers in [0, rd) can be represented exactly, where r is std::numeric_limits<type>::radix
and d is std::numeric_limits<type>::digits
.
This in turn seems to imply that an integer with no more than std::numeric_limits<type>::digits10
base-10 digits can be represented exactly.
Aside: There are some problems with the C++ standard’s definition of std::numeric_limits<type>::digits10
.
The standard says this is the “Number of base 10 digits that can be represented without change.” Is that supposed to be just simple base 10 digits, i.e., integers, or is it a statement about precision throughout the range of the format? A footnote, which is not normative, says this is equivalent to FLT_DIG, DBL_DIG, and LDBL_DIG, which are defined by way of the C standard. The C standard gives two definitions in one statement:
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,
and:
p log10 b if b is a power of 10
floor((p-1) log10 b) otherwise
I do not believe the former is a good definition. The latter gives us 7 for IEEE-754 32-bit binary floating-point, but 1.5e-45 is a floating-point number with 2 decimal digits, and rounding it to IEEE-754 32-bit binary floating-point and back gives 1.401…e-45 (because it is in the subnormal interval). So it is not true that any floating-point number with 7 decimal digits can be rounded to floating-point and back again without change to the 7 decimal digits.