关于素数验证算法

这几天太颓废,天天荣耀加知乎,晚上的时候偶然在知乎上刷到一个关于2333。。和素数的问题,具体也记不清了,毕竟我对数论一无所知。因为最近才学的python,于是想用python来计算一下233。。。这样下去哪些是素数呢?

判断素数嘛,第一个想到的就是慢慢试着除啦,然后我就这么写了,然而速度。。绝望 怎么办 优化呗
首先 试除的范围可以缩减到sqrt(n),其次试除的数要有选择,不能使一些小质数的倍数,如(2,3,5,7,11)的倍数,然而改进之后速度还是不行
这里面还有个小问题,我算的时候发现虽然python3整数的范围只要内存够就没限制,但是除法似乎是有精度的,我的程序中算到23333.。(20个3)的时候精度就有问题了,所以要使用decimal模块进行高精度除法

闲话说太多了。。总而言之,最关键的是想要判断是否是素数,有很多比试除法要好很多的算法。具体请看http://www.matrix67.com/blog/archives/234和http://www.matrix67.com/blog/archives/5100我没有仔细看(太懒),直接使用的Fermat小定理,速度一下子快了好多。。回头我还得仔细看看,我可能用错了??

from random import *
def fast(a,b,p):
    a = a
    p = p
    ret = 1
    while b!=0:
        if b&1==1:
            ret = ((ret%p)*(a%p))%p
        a = ((a%p)**2)%p
        b //= 2
    return ret

def isPrime(x):
    assert isinstance(x,int) and x>0
    if x==1:
        return False
    elif x in [2,3,5,7,11]:
        return True
    for j in range(50):
        r = randrange(2,x)
        if fast(r,x-1,x)!=1:
            return False
    return True


if __name__=='__main__':
    x = 2
    for i in range(1,1000):
        x *= 10
        x += 3
        f = 0
        for j in range(50):
            r = randrange(2,x)
            if fast(r,x-1,x)!=1:
                f = 1
                break
        if f==0:
            print('{:2} {} is a prime'.format(i,x))
    print('done')

运行结果:

 1 23 is a prime
 2 233 is a prime
 3 2333 is a prime
 4 23333 is a prime
10 23333333333 is a prime
16 23333333333333333 is a prime
22 23333333333333333333333 is a prime
53 233333333333333333333333333333333333333333333333333333 is a prime
91 23333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
94 23333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
106 23333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
138 2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
210 2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
282 2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
522 2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
597 2333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 is a prime
done

一不小心又熬夜了,赶紧睡了
话说我之前试着用开了三个进程多进程来跑试除法,下午到现在凌晨还没出结果。。

 1 23:  23
 2 233:  233
 3 2333:  2333
 4 23333:  23333
 5 233333: 353  661
 6 2333333: 19 227  541
 8 233333333: 29 47 193  887
 7 23333333: 17  1372549
 9 2333333333: 10163  229591
11 233333333333: 569  410076157
12 2333333333333: 1091  2138710663
10 23333333333:  23333333333
13 23333333333333: 31  752688172043
15 2333333333333333: 311 749803  10006201
14 233333333333333: 59  3954802259887
18 2333333333333333333: 337 1453  4765201503353
19 23333333333333333333: 11661407  2000902063819
20 233333333333333333333: 109 23909  89534183063893
17 233333333333333333: 58119797  4014696289
16 23333333333333333:  23333333333333333
23 233333333333333333333333: 17 17 23 7591 20207311  228846139
21 2333333333333333333333: 1583 408413539  3609073609
25 23333333333333333333333333: 379 13127  4689991872244085401
26 233333333333333333333333333: 75181 209717  14799091342159429

当然试除法有个无敌的优点:可以直接分解质因数,其他的算法都只能是判断,而目前大整数的质因数分解到现在都没什么好的算法,慢慢除吧。。

你可能感兴趣的:(备忘)