[python] 파이썬에서 정수의 길이

파이썬에서 정수의 자릿수를 어떻게 찾습니까?



답변

정수의 자릿수와 같이 정수의 길이를 원하면 항상 문자열처럼 변환 str(133)하고 길이를 찾을 수 len(str(123))있습니다.


답변

문자열로 변환하지 않고

import math
digits = int(math.log10(n))+1

0과 음수도 처리하려면

import math
if n > 0:
    digits = int(math.log10(n))+1
elif n == 0:
    digits = 1
else:
    digits = int(math.log10(-n))+2 # +1 if you don't count the '-' 

아마도 함수에 넣기를 원할 것입니다 🙂

다음은 몇 가지 벤치 마크입니다. 는 len(str())심지어 아주 작은 숫자 뒤에 이미

timeit math.log10(2**8)
1000000 loops, best of 3: 746 ns per loop
timeit len(str(2**8))
1000000 loops, best of 3: 1.1 µs per loop

timeit math.log10(2**100)
1000000 loops, best of 3: 775 ns per loop
 timeit len(str(2**100))
100000 loops, best of 3: 3.2 µs per loop

timeit math.log10(2**10000)
1000000 loops, best of 3: 844 ns per loop
timeit len(str(2**10000))
100 loops, best of 3: 10.3 ms per loop


답변

모든 math.log10 솔루션은 문제를 제공합니다.

math.log10은 빠르지 만 숫자가 999999999999997보다 큰 경우 문제가 발생합니다. 이는 float에 0.9가 너무 많아 결과가 반올림되기 때문입니다.

해결책은 해당 임계 값을 초과하는 숫자에 while 카운터 방법을 사용하는 것입니다.

이를 더욱 빠르게하려면 10 ^ 16, 10 ^ 17 등을 작성하고 변수를 목록에 저장하십시오. 그렇게하면 테이블 조회와 같습니다.

def getIntegerPlaces(theNumber):
    if theNumber <= 999999999999997:
        return int(math.log10(theNumber)) + 1
    else:
        counter = 15
        while theNumber >= 10**counter:
            counter += 1
        return counter


답변

Python 2.* int은 Python 빌드에 따라 4 또는 8 바이트 (32 또는 64 비트)를 사용합니다. sys.maxint( 2**31-132 비트 정수의 2**63-1경우 64 비트 정수의 경우)는 두 가지 가능성 중 어느 것을 얻을 수 있는지 알려줍니다.

Python 3에서 ints ( longPython 2의 s 와 같은 )는 사용 가능한 메모리 양까지 임의의 크기를 사용할 수 있습니다. sys.getsizeof그것은 비록 당신에게 주어진 가치에 대해 좋은 표시를 제공 않습니다 일부 고정 오버 헤드 수 :

>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28

다른 답변에서 알 수 있듯이 정수 값의 문자열 표현에 대해 생각하고 len있다면 그 표현을 기본 10 또는 다른 식으로 가져 가십시오 !


답변

이 질문을 한 지 몇 년이 지났지 만 정수 길이를 계산하기 위해 여러 가지 방법의 벤치 마크를 작성했습니다.

def libc_size(i):
    return libc.snprintf(buf, 100, c_char_p(b'%i'), i) # equivalent to `return snprintf(buf, 100, "%i", i);`

def str_size(i):
    return len(str(i)) # Length of `i` as a string

def math_size(i):
    return 1 + math.floor(math.log10(i)) # 1 + floor of log10 of i

def exp_size(i):
    return int("{:.5e}".format(i).split("e")[1]) + 1 # e.g. `1e10` -> `10` + 1 -> 11

def mod_size(i):
    return len("%i" % i) # Uses string modulo instead of str(i)

def fmt_size(i):
    return len("{0}".format(i)) # Same as above but str.format

(libc 함수에는 포함되지 않은 일부 설정이 필요합니다)

size_expBrian Preslopsky, size_strGeekTantra, size_mathJohn La Rooy 덕분입니다

결과는 다음과 같습니다.

Time for libc size:      1.2204 μs
Time for string size:    309.41 ns
Time for math size:      329.54 ns
Time for exp size:       1.4902 μs
Time for mod size:       249.36 ns
Time for fmt size:       336.63 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.240835x)
+ math_size (1.321577x)
+ fmt_size (1.350007x)
+ libc_size (4.894290x)
+ exp_size (5.976219x)

(면책 조항 :이 기능은 입력 1-1,000,000에서 실행됩니다)

여기에 대한 결과입니다 sys.maxsize - 100000으로는 sys.maxsize:

Time for libc size:      1.4686 μs
Time for string size:    395.76 ns
Time for math size:      485.94 ns
Time for exp size:       1.6826 μs
Time for mod size:       364.25 ns
Time for fmt size:       453.06 ns
In order of speed (fastest first):
+ mod_size (1.000000x)
+ str_size (1.086498x)
+ fmt_size (1.243817x)
+ math_size (1.334066x)
+ libc_size (4.031780x)
+ exp_size (4.619188x)

보다시피, mod_size( len("%i" % i))는 사용하는 것보다 약간 빠르며 str(i)다른 것보다 훨씬 빠릅니다.


답변

수가하자 n자릿수 다음 수 n에 의해 주어진다 :

math.floor(math.log10(n))+1

이것은 + ve 정수 <10e15에 대한 정답을 제공합니다. 리턴 타입의 math.log10킥과 그 대답 의 정밀도 한계는 1만큼 떨어질 수 있습니다 len(str(n)). 이를 위해서는 O(log(n))10의 거듭 제곱을 반복하는 것과 동일한 시간 이 필요합니다 .

이 한계에 관심을 가져 주신 @SetiVolkylany에게 감사드립니다. 겉보기에 올바른 솔루션이 구현 세부 사항에 얼마나 심각한 지 놀랍습니다.


답변

글쎄, 문자열로 변환하지 않고 나는 다음과 같은 일을 할 것이다.

def lenDigits(x):
    """
    Assumes int(x)
    """

    x = abs(x)

    if x < 10:
        return 1

    return 1 + lenDigits(x / 10)

미니멀리스트 재귀 FTW