What is the most simple/elegant way to calculate the length of a number written as text?

c++, fixed-length-record

Solution

You could do it with a little template meta programming:

//NunLength_interal does the actual calculation. 
template <unsigned num>
struct NumLength_internal
{ enum { value = 1 + NumLength_internal<num/10>::value }; };

template <>
struct NumLength_internal<0>
{ enum { value = 0 }; };

//NumLength is a wrapper to handle zero. For zero we want to return
//a length of one as a special case.
template <unsigned num>
struct NumLength
{ enum { value = NumLength_internal<num>::value };};

template <>
struct NumLength<0>
{ enum { value = 1 }; };

This should work for anything now. For example:

cout << NumLength<0>::value      << endl; // writes: 1
cout << NumLength<5>::value      << endl; // writes: 1
cout << NumLength<10>::value     << endl; // writes: 2
cout << NumLength<123>::value    << endl; // writes: 3
cout << NumLength<0x8000>::value << endl; // writes: 5

This is all handled at compile time.

Edit: I added another layer to handle the case when the number passed in is zero.

Problem

Given the maximum possible value, how to simply express the space needed to write such number in decimal form as text ? The real task: logging process ids (`pid_t`) with fixed length, using gcc on Linux. It'd be good to have a compile time expression to be used in the `std::setw()` iomanipulator. I have found that linux/threads.h header contains a `PID_MAX` value with the maximum pid allocated to a process. So having ``` #define LENGTH(t) sizeof(#t)-1 ``` the `LENGTH(PID_MAX)` would be a compile time expression, but unfortunatelly this number is defined in hexa: ``` #define PID_MAX 0x8000 ``` My current best solution is a bit oddish ``` static_cast<int>( ::floor( ::log(PID_MAX)/::log(10) + 1 ) ); ``` But this is calculated runtime and uses functions from math.h

Original source