数字的第一个数字

时间:2016-08-13 23:16:23

标签: python

我想要一个无限循环的斐波那契系列的前9位和后9位数。单独运行测试,使用模数运算符no得到最后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]

1 个答案:

答案 0 :(得分:1)

以下是获得前30000前缀的几个版本和时间。为简单起见,我遗漏了前两个数和最后一个数字。

  • fibby1是使用str(b)[:9]
  • 的原始方式
  • fibby2会跟踪除以10的适当功率。
  • fibby3保留ab中的前9位数字以及AB中的其余数字。与fibby2相比,这可以避免将较大的b除以10的大功率。大数字只会被加/减/比较,或乘以一个小数字。
  • fibby4使用@therefromhere建议的math.log10
  • fibby5使用decimal模块。

输出:

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

为了进行比较,我还尝试了str(b % 10**9),即最后九位数,这需要0.506秒。对于前九位数,我的快速解决方案

代码:

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