Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Width to fit any value of an unsigned (natural) number

Tags:

c++

c++14

Background

I have a logging system that outputs records to a std::ostream. Each record is annotated with a counter that is increased by one with each output, like this:

=====  Batch # 5  =====
  This is the fifth record
=====  Batch # 19  =====
  This is the nineteenth record
=====  Batch # 187  =====
  Who knows to spell *that*?

The counter is a std::size_t, i.e., an unsigned integer.

Problem

As it is now, numbers are outputted without any padding, which looks ugly. I would like to achieve this:

=====  Batch #     5  =====
  This is the fifth record
=====  Batch #    19  =====
  ...
=====  Batch #   187  =====
=====  Batch # 12345  =====

Making the stream object handle this can be achieved with std::setw. However, I still need to know how many digits takes the base-10 representation of the maximum possible value.

Request

The solution must compute statically (i.e. at translation-time) how many digits takes the base-10 representation of the maximum possible value of a std::size_t. I will welcome any method that meets this requirement, although I will prefer those that employ C++14's (relaxed) constexprs.

Hints and things I have tried

It seems that the representation of a natural number N in base-B takes as many digits as the truncation of (the B-index logarithm of N) plus 1. For example, the value 100 is three digits long in base 10, and the common logarithm of 100 plus 1 is 3; the value 1234 is four digits long in base 10, and the truncation of (the common logarithm of 1234) plus 1 is 4. In pseudo-something:

digits( value , base ) = floor( logarithm( radicand=value , index=base ) ) + 1

I apologize for the lazyness of the explanation and the formatting; if someone knows a better way, please, feel free to edit my post or to suggest it. You can try this here. It seems to work, but I haven't thoroughly verified it.

As for the maximum value a std::size_t object can hold, it is std::numeric_limits<std::size_t>::max().


I intend to answer this question. I will give some time before posting my answer, and wait more before accepting any.

like image 747
Kalrish Avatar asked Feb 12 '23 08:02

Kalrish


1 Answers

Seems that std::numeric_limits::digits10 is what you want. live example

like image 91
ForEveR Avatar answered Feb 16 '23 04:02

ForEveR