정수로 자릿수를 결정하는 효율적인 방법 몇 자릿수가 있는지 결정하는 가장

C ++에서 정수에 몇 자릿수가 있는지 결정하는 가장 효율적인 방법은 무엇입니까 ?



답변

음, 정수의 크기를 알고 있다고 가정하면 가장 효율적인 방법은 조회입니다. 훨씬 짧은 대수 기반 접근 방식보다 빠릅니다. ‘-‘계산에 신경 쓰지 않으면 + 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];
}


답변

가장 간단한 방법은 다음과 같습니다.

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

log10은 다음에서 정의됩니다. <cmath> 또는에<math.h> 있습니다. 여기에 게시 된 다른 것보다 빠른지 확인하려면이 프로파일을 작성해야합니다. 부동 소수점 정밀도와 관련하여 이것이 얼마나 강력한 지 잘 모르겠습니다. 또한 인수는 음수 값으로 부호가 없으며 로그는 실제로 혼합되지 않습니다.


답변

아마도 나는 그 질문을 잘못 이해했지만 그렇지 않습니까?

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)))))))));
}  


답변

int digits = 0; while (number != 0) { number /= 10; digits++; }

참고 : “0”은 0 자리입니다. 1 자리 숫자가 0으로 나타나려면 다음을 사용하십시오.

int digits = 0; do { number /= 10; digits++; } while (number != 0);

(감사합니다. Kevin Fegan)

결국, 프로파일 러를 사용하여 여기에있는 모든 답변 중 어느 것이 컴퓨터에서 더 빠를 지 알 수 있습니다 …


답변

실제 농담이있다 가장 효율적인 방법은 (자릿수는 컴파일 시간에 계산됩니다)

template <unsigned long long N, size_t base=10>
struct numberlength
{
    enum { value = 1 + numberlength<N/base, base>::value };
};

template <size_t base>
struct numberlength<0, base>
{
    enum { value = 0 };
};

서식, 입력 요소 등에서 숫자 필드에 필요한 너비를 결정하는 데 유용 할 수 있습니다.


답변

수락 한 답변의 훨씬 짧은 버전은 Bit Twiddling Hacks 를 참조하십시오 . 또한 큰 상수를 먼저 확인하여 입력이 정상적으로 분포되면 답변을 더 빨리 찾을 수 있다는 이점이 있습니다. (v >= 1000000000)값의 76 %를 포착하므로 평균적으로 먼저 확인하는 것이 더 빠릅니다.


답변

문자열로 변환 한 후 내장 함수 사용

unsigned int i;
cout<< to_string(i).length()<<endl;