파이썬에서 정수의 자릿수를 어떻게 찾습니까?
답변
정수의 자릿수와 같이 정수의 길이를 원하면 항상 문자열처럼 변환 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-1
32 비트 정수의 2**63-1
경우 64 비트 정수의 경우)는 두 가지 가능성 중 어느 것을 얻을 수 있는지 알려줍니다.
Python 3에서 int
s ( long
Python 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_exp
Brian Preslopsky, size_str
GeekTantra, size_math
John 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