2016-08-13 5 views
2

무한 루프의 경우 fibonocci 시리즈의 처음 9 자리와 마지막 9 자리를 원합니다. 테스트를 개별적으로 실행하면 모듈러스 연산자를 사용하여 마지막 9 자리에 대해 더 나은 결과를 얻을 수 있습니다. 첫 9 자리와 비교할 수 있습니다. 내가 int(str(b)[::-1])%10**9, b/(10**(len(str(b))-9)) 같은 다른 테스트를 실행했지만 여전히 같은 결과. 나는 숫자가 높은 숫자의 문자열 변환 때문에 발생한다고 생각한다. 문자열로 변환하지 않고 처음 9 자리를 인쇄하는 다른 방법이 있습니까?첫 번째 숫자 숫자

def fibby(): 
    a,b = 1,1 
    yield [a,a] 
    yield [b,b] 
    while True: 
     a,b = b,a+b 
     yield [str(b)[:9], b%10**9] 
+0

당신이 "더 나은 결과"무엇을 의미합니까? 어떤 결과를 얻고 그 결과가 잘못 되었습니까? – ypnos

+2

정수를 문자열로 변환하는 것보다 더 효율적 일지 모르겠지만 'math.log10()'을 사용하여 숫자를 계산할 수 있고,'// '를 수행하여 정수를 반올림하여 반입 할 수 있습니다 가장 중요한 인물. –

+0

시간 성능면에서 의미가 있습니다. MSB가 2 분 이상 걸릴 때 (개별적으로 테스트하는 경우) 최소 유효 자릿수는 6 **에서 10 ** 8까지 나타납니다. MSB가 LSB의 타임 매치 일 수 있습니까? –

답변

1

다음은 첫 번째 30000 접두어를 가져 오는 몇 가지 버전과 타이밍입니다. 나는 단순화를 위해 처음 두 수확과 마지막 자릿수를 버렸다.

  • fibby1str(b)[:9]을 사용하는 원래의 방법입니다.
  • fibby2은 10의 적절한 출력을 추적합니다.
  • fibby3ab에 처음 9 자리를 유지하고 나머지 숫자는 AB에 유지합니다. fibby2과 비교하여 대용량은 10 진수로 나누어지는 것을 피합니다. 큰 수는 더하기/빼기/비교되거나 작은 수로 곱합니다.
  • fibby4은 @therefromhere가 제안한 math.log10을 사용합니다.
  • fibby5decimal 모듈을 사용합니다.

출력은 : 나는 또한 str(b % 10**9), 즉, 지난 9 자리 숫자를 시도 그냥 비교를 위해

All agree? True 
fibby1: 24.835 seconds 
fibby2: 0.289 seconds 
fibby3: 0.201 seconds 
fibby4: 2.802 seconds 
fibby5: 0.216 seconds 

, 그것은 0.506 초 걸렸습니다. 처음 9 자리 숫자에 대한 나의 빠른 해결책보다 이 더 느립니다.입니다.

코드 :

def fibby1(): 
    a, b = 1, 1 
    while True: 
     yield str(b)[:9] 
     a, b = b, a+b 

def fibby2(): 
    a, b = 1, 1 
    div = 1 
    while True: 
     while True: 
      front = b // div 
      if front < 10**9: 
       break 
      div *= 10 
     yield str(front) 
     a, b = b, a+b 

def fibby3(): 
    a,b = 1,1 
    A,B,C = 0,0,1 
    while True: 
     yield str(b) 
     a, b = b, a+b 
     A, B = B, A+B 
     if B >= C: 
      B -= C 
      b += 1 
     if b >= 10**9: 
      A += a%10 * C 
      B += b%10 * C 
      a //= 10 
      b //= 10 
      C *= 10 

def fibby4(): 
    from math import log10 
    a, b = 1, 1 
    while True: 
     yield str(b // 10**max(0, int(log10(b) - 8))) 
     a, b = b, a+b 

def fibby5(): 
    from decimal import Decimal, getcontext 
    getcontext().prec = 7000 # enough for n = 30000 
    a, b = Decimal(1), Decimal(1) 
    while True: 
     yield str(b)[:9] 
     a, b = b, a+b 

from timeit import timeit 
from itertools import islice 
from time import time 

n = 30000 
t0 = time() 
list1 = list(islice(fibby1(), n)) 
t1 = time() 
list2 = list(islice(fibby2(), n)) 
t2 = time() 
list3 = list(islice(fibby3(), n)) 
t3 = time() 
list4 = list(islice(fibby4(), n)) 
t4 = time() 
list5 = list(islice(fibby5(), n)) 
t5 = time() 
print('All agree?', list1 == list2 == list3 == list4 == list5) 
print('fibby1: %6.3f seconds' % (t1 - t0)) 
print('fibby2: %6.3f seconds' % (t2 - t1)) 
print('fibby3: %6.3f seconds' % (t3 - t2)) 
print('fibby4: %6.3f seconds' % (t4 - t3)) 
print('fibby5: %6.3f seconds' % (t5 - t4)) 
관련 문제