What Are the Maximum Number of Base-10 Digits in the Integral Part of a Floating Point Number

末鹿安然 提交于 2020-01-15 03:03:11

问题


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;

回答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 type T and back to decimal form, without change due to rounding or overflow. For base-radix types, it is the value of digits (digits-1 for floating-point types) multiplied by log10(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

10d < 2b-1

In the case of an IEEE754 binary64 (the standard double in C++ on most systems nowadays), then b = 53, and 2b-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 = 2b+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.




回答2:


The value that you are looking for is max_exponent10 which:

Is the largest positive number n such that 10n is a representable finite value of the floating-point type

Because of this relationship:

log10x = n
10n = 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 10n + 1 would be larger than numeric_limits<T>::max() but 10n 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 log101 = 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:

http://coliru.stacked-crooked.com/a/443e4d434cbcb2f6



来源:https://stackoverflow.com/questions/39776532/what-are-the-maximum-number-of-base-10-digits-in-the-integral-part-of-a-floating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!