Efficient way to determine number of digits in an integer

Viewed 274250

What is a very efficient way of determining how many digits there are in an integer in C++?

33 Answers
int x = 1000;
int numberOfDigits = x ? static_cast<int>(log10(abs(x))) + 1 : 1;

If faster is more efficient, this is a improvement on andrei alexandrescu's improvement. His version was already faster than the naive way (dividing by 10 at every digit). The version below is constant time and faster at least on x86-64 and ARM for all sizes, but occupies twice as much binary code, so it is not as cache-friendly.

Benchmarks for this version vs alexandrescu's version on my PR on facebook folly.

Works on unsigned, not signed.

inline uint32_t digits10(uint64_t v) {
  return  1
        + (std::uint32_t)(v>=10)
        + (std::uint32_t)(v>=100)
        + (std::uint32_t)(v>=1000)
        + (std::uint32_t)(v>=10000)
        + (std::uint32_t)(v>=100000)
        + (std::uint32_t)(v>=1000000)
        + (std::uint32_t)(v>=10000000)
        + (std::uint32_t)(v>=100000000)
        + (std::uint32_t)(v>=1000000000)
        + (std::uint32_t)(v>=10000000000ull)
        + (std::uint32_t)(v>=100000000000ull)
        + (std::uint32_t)(v>=1000000000000ull)
        + (std::uint32_t)(v>=10000000000000ull)
        + (std::uint32_t)(v>=100000000000000ull)
        + (std::uint32_t)(v>=1000000000000000ull)
        + (std::uint32_t)(v>=10000000000000000ull)
        + (std::uint32_t)(v>=100000000000000000ull)
        + (std::uint32_t)(v>=1000000000000000000ull)
        + (std::uint32_t)(v>=10000000000000000000ull);
}

sample console output

long long num = 123456789;
int digit = 1;
int result = 1;

while (result != 0) 
{
    result = num / 10;
    if (result != 0)
    {
        ++digit;
    }
    num = result;
}

cout << "Your number has " << digit << "digits" << endl;

Use the best and efficient way of log10(n) approach which gives you the desired result in just logarithmic time.

For negative number abs() converts it into positive number and for the number 0, the if condition stops you from proceeding further and prints the output as 0.

#include <iostream>
#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n; std::cin >> n;
    if(n)
        std::cout << floor(log10(abs(n))+1) << std::endl;
    else
        std::cout << 0 << std::endl;
    return 0;
}
int num,dig_quant = 0;
cout<<"\n\n\t\t--Count the digits in Number--\n\n";
cout<<"Enter Number: ";
cin>>num;
for(int i = 1; i<=num; i*=10){
    if(num / i  > 0){
      dig_quant += 1;
    }
}
 cout<<"\n"<<number<<" include "<<dig_quant<<" digit"
 cout<<"\n\nGoodbye...\n\n";

I was working on a program that required me to check if the user correctly answered how many digits were in a number, so i had to develop a way to check the amount of digits in an integer. It ended up being a relatively easy thing to solve.

double check=0, exponent=1000;

while(check<=1)
{
    check=number/pow(10, exponent);
    exponent--;
}

exponent=exponent+2;
cout<<exponent<<endl;

This ended up being my answer which currently works with numbers with less than 10^1000 digits (can be changed by changing the value of exponent).

P.S. I know this answer is ten years late but I got here on 2020 so other people might use it.

You can use this recursive function, which calls itself while its argument is greater or equal to 10.

int numDigits(int n) {
    return n >= 10 ? numDigits(n / 10) + 1 : 1;
}

Example usage:

#include <iostream>

int numDigits(int n) {
    return n >= 10 ? numDigits(n / 10) + 1 : 1;
}

int main() {
    int values[] = {0, 4, 10, 43, 789, 1500};
    for (int n : values) {
        std::cout << n << ": " << numDigits(n) << '\n';
    }
    return 0;
}

Output:

0: 1
4: 1
10: 2
43: 2
789: 3
1500: 4

Here is neat trick that uses fact that intLog2 is easy and fast and that: log10(x) = log2(x)/log2(10). Rounding issue have to be taken into account.

demo

constexpr int intPow(int base, int n) {
    int result = 1;
    while (n) {
        if (n & 1 == 1)
            result *= base;
        base *= base;
        n >>= 1;
    }
    return result;
}

constexpr int intLog2(int x) {
    int result = -1;
    while (x) {
        x >>= 1;
        ++result;
    }
    return result;
}

constexpr int intLog10(int x) {
    constexpr int powersOf10[]{1,         10,        100,     1000,
                               10000,     100000,    1000000, 10000000,
                               100000000, 1000000000};
    auto aprox = (intLog2(x) + 1) * 1233 >> 12;
    return aprox - (x < powersOf10[aprox]);
}

All is done on integers. No divisions, so should be quite fast, but lookup table is probably faster (maybe will provide benchmark for that).

You can use this to calculate the number of digits on compile time:

C++20 solution:

template<std::integral auto num>
constexpr int number_of_digits = num >= -9 && num <= 9 ? 1 : 1 + number_of_digits<num / 10>;

Works for negative numbers, zero and positive numbers.

Note: to make it work with C++14 change "std::integral auto" to "long long".

Note: if you want the minus sign in negative numbers to also be counted, then change -9 to 0;

Usage example:

int k = number_of_digits<101>; // k = 3

The way this works is that a number is going to be divided by 10 recursively until it becomes a single digit, in which case we finish by adding +1 to the total sum.

Related