3

Why std::numeric_limits<Any Int Type>::digits10 is one less than it can be?

For example, std::numeric_limits<int8_t>::digits10 == 2, but 100 consists of three digits.

Or, std::numeric_limits<int64_t>::digits10 == 18, but INT64_MAX (9'223'372'036'854'775'807) consists of 19 digits.

vladon
  • 8,158
  • 2
  • 47
  • 91

2 Answers2

2

std::numeric_limits<T>::digits10 is the guaranteed number of digits in a sense that a number with that many digits can be represented in type T without causing overflow or loss of information.

E.g. std::numeric_limits<int64_t>::digits10 cannot be 19 becuase 9'223'372'036'854'775'808 has 19 digits but is not representable in int64_t.

In general case such guaranteed value of digits<N> will always suffer from this "one less" discrepancy on platforms where digits<N> is not a power of radix used for internal representation. In non-exotic cases radix is 2. Since 10 is not a power of 2, digits10 is smaller by 1 than the length of the max value.

If std::numeric_limits<T> included digits16 or digits8 these values would've been "precise" for radix 2 platforms.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

The definition of numeric_limits::digits is as follows:

The value of std::numeric_limits::digits10 is 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.

This means that int8_t is 2 digits because there are some 3 digit numbers you can't represent with an int8_t (i.e. 999)

Russ
  • 31
  • 1