basically I want to return the number of digits in the int -> values like this:
(int)1 => 1
(int)123 => 3
(int)12345678 => 8
I kno
Probably much faster than using log or int-to-string conversion and without using any library functions is this:
int nDigits(int i)
{
if (i < 0) i = -i;
if (i < 10) return 1;
if (i < 100) return 2;
if (i < 1000) return 3;
if (i < 10000) return 4;
if (i < 100000) return 5;
if (i < 1000000) return 6;
if (i < 10000000) return 7;
if (i < 100000000) return 8;
if (i < 1000000000) return 9;
return 10;
}
EDIT after Jeff Yates concerns:
For those who worry about int sizes different from 32-bits (similar to pmg's solution but still faster because multiplication is faster than division :-)
#include <limits.h>
#define PO10_LIMIT (INT_MAX/10)
int nDigits(int i)
{
int n,po10;
if (i < 0) i = -i;
n=1;
po10=10;
while(i>=po10)
{
n++;
if (po10 > PO10_LIMIT) break;
po10*=10;
}
return n;
}
If your integer value (e.g. 12345678u
) is a compile-time constant, you can let the compiler determine the length for you:
template<typename T>
constexpr unsigned int_decimal_digits(T value)
{
return ( value / 10
? int_decimal_digits<T>(value/10) + 1
: 1 );
}
Usage:
unsigned n = int_decimal_digits(1234);
// n = 4
#include <limits.h>
unsigned m = int_decimal_digits(ULLONG_MAX);
// m = maximum length of a "long long unsigned" on your platform
This way, the compiler will compute the number of decimal places automatically, and fill in the value as a constant. It should be the fastest possible solution, because there is no run-time computation involved and integer constants are usually put into the instruction opcodes. (This means that they travel by instruction pipeline, not by data memory/cache.) However, this requires a compiler that supports C++11.
Use logarithms base 10:
int length = (int)floor(log10((float)number)) + 1; // works for >0
A more general solution, especially if you want to know the length for purposes of printing with printf()
variants is:
snprintf(NULL, 0, "%d", myint);
The return value should tell you the length of the string that would be printed.
Here's another option
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
This is faster than using log10
, but slower than Curd's option with the cascading tests. However it doesn't assume int
s are 32 bits :-)
use
int d = (value == 0 ? 1 : (int)(log10(value)+1));
Note that this doesnt work for negative numbers, you'll have to use
int d = (value == 0 ? 1 : ((int)(log10(fabs(value))+1) + (value < 0 ? 1 : 0)));
which adds 1 for the minus sign, if value
is negative.