I want to know if there is something in the standard, like a #define
or something in numeric_limits
which would tell me the maximum number of base-10 digits in the integral part of a floating point type.
For example, if I have some floating point type the largest value of which is: 1234.567. I'd like something defined in the standard that would tell me 4 for that type.
Is there an option to me doing this?
template <typename T>
constexpr auto integral_digits10 = static_cast<int>(log10(numeric_limits<T>::max())) + 1;
As Nathan Oliver points out in the comments, C++ provides std::numeric_limits<T>::digits10
.
the number of base-10 digits that can be represented by the type
T
without change, that is, any number with this many decimal digits can be converted to a value of typeT
and back to decimal form, without change due to rounding or overflow. For base-radix
types, it is the value ofdigits
(digits
-1 for floating-point types) multiplied by log 10 (radix
) and rounded down.
The explanation for this is explained by Rick Regan here . In summary, if your binary floating point format can store b bits in the significand, then you are guaranteed to be able to round-trip up to d decimal digits, where d is the largest integer such that
10 d < 2 b -1
In the case of an IEEE754 binary64 (the standard double
in C++ on most systems nowadays), then b = 53, and 2 b -1 = 4,503,599,627,370,496, so the format is only guaranteed to be able to represent d = 15 digits.
However this result holds for all digits, whereas you just ask about the integral part. However we can easily find a counterexample by choosing x = 2 b +1, which is the smallest integer not representable by the format: for binary64 this is 9,007,199,254,740,993, which also happens to have 16 digits, and so will need to be rounded .
The value that you are looking for is max_exponent10
which:
Is the largest positive number n such that 10 n is a representable finite value of the floating-point type
Because of this relationship:
log 10 x = n
10 n = x
Your calculation is doing, is finding n the way the first equation works:
log10(numeric_limits<T>::max())
The definition of max_exponent10
is explaining that it is using a 10 n + 1 would be larger than numeric_limits<T>::max()
but 10 n is less than or equal to numeric_limits<T>::max()
. So numeric_limits<T>::max_exponent10
is what you're looking for.
Note that you will still need the + 1
as in your example, to account for the 1's place. (Because log 10 1 = 0) So your the number of 10-based digits required to represent numeric_limits<T>::max()
will be:
numeric_limits<T>::max_exponent10 + 1
If you feel like validating that by hand you can check here:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.