Moyen efficace pour déterminer le nombre de chiffres dans un entier

Moyen efficace pour déterminer le nombre de chiffres dans un entier

Eh bien, le moyen le plus efficace, en supposant que vous connaissiez la taille de l'entier, serait une recherche. Devrait être plus rapide que l'approche beaucoup plus courte basée sur le logarithme. Si vous ne vous souciez pas de compter le '-', supprimez le + 1.

// generic solution
template <class T>
int numDigits(T number)
{
    int digits = 0;
    if (number < 0) digits = 1; // remove this line if '-' counts as a digit
    while (number) {
        number /= 10;
        digits++;
    }
    return digits;
}

// partial specialization optimization for 32-bit numbers
template<>
int numDigits(int32_t x)
{
    if (x == MIN_INT) return 10 + 1;
    if (x < 0) return numDigits(-x) + 1;

    if (x >= 10000) {
        if (x >= 10000000) {
            if (x >= 100000000) {
                if (x >= 1000000000)
                    return 10;
                return 9;
            }
            return 8;
        }
        if (x >= 100000) {
            if (x >= 1000000)
                return 7;
            return 6;
        }
        return 5;
    }
    if (x >= 100) {
        if (x >= 1000)
            return 4;
        return 3;
    }
    if (x >= 10)
        return 2;
    return 1;
}

// partial-specialization optimization for 8-bit numbers
template <>
int numDigits(char n)
{
    // if you have the time, replace this with a static initialization to avoid
    // the initial overhead & unnecessary branch
    static char x[256] = {0};
    if (x[0] == 0) {
        for (char c = 1; c != 0; c++)
            x[c] = numDigits((int32_t)c);
        x[0] = 1;
    }
    return x[n];
}

Le plus simple est de faire :

unsigned GetNumberOfDigits (unsigned i)
{
    return i > 0 ? (int) log10 ((double) i) + 1 : 1;
}

log10 est défini dans <cmath> ou <math.h> . Vous auriez besoin de profiler ceci pour voir s'il est plus rapide que n'importe lequel des autres publiés ici. Je ne sais pas à quel point cela est robuste en ce qui concerne la précision de la virgule flottante. De plus, l'argument n'est pas signé car les valeurs négatives et le journal ne se mélangent pas vraiment.


J'ai peut-être mal compris la question, mais est-ce que cela ne suffit pas ?

int NumDigits(int x)  
{  
    x = abs(x);  
    return (x < 10 ? 1 :   
        (x < 100 ? 2 :   
        (x < 1000 ? 3 :   
        (x < 10000 ? 4 :   
        (x < 100000 ? 5 :   
        (x < 1000000 ? 6 :   
        (x < 10000000 ? 7 :  
        (x < 100000000 ? 8 :  
        (x < 1000000000 ? 9 :  
        10)))))))));  
}