一種特殊的判斷素數的方法

http://blog.csdn.net/huang_miao_xin/article/details/51331710(轉載地址)

首先看一個關於質數分佈的規律:大於等於5的質數一定和6的倍數相鄰。例如5和7,11和13,17和19等等;

證明:令x≥1,將大於等於5的自然數表示如下:

······ 6x-1,6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1 ······

可以看到,不在6的倍數兩側,即6x兩側的數爲6x+2,6x+3,6x+4,由於2(3x+1),3(2x+1),2(3x+2),所以它們一定不是素數,再除去6x本身,顯然,素數要出現只可能出現在6x的相鄰兩側。這裏有個題外話,關於孿生素數,有興趣的道友可以再另行了解一下,由於與我們主題無關,暫且跳過。這裏要注意的一點是,在6的倍數相鄰兩側並不是一定就是質數。

根據以上規律,判斷質數可以6個爲單元快進,即將方法(2)循環中i++步長加大爲6,加快判斷速度爲什麼這樣呢?

證明如下:

首先我們要知道,對於一個連續的3個數,是不是一定有一個模3餘0,一個模3餘1,一個模3餘2

我們目前已經知道了要判斷的數 n = 6x+1 或 6x-1

如果我們每次增1一個一個的循環則一定會遍歷下面6種數

6i-1,  6i,  6i+1,  6i+2,  6i+3,  6i+4

1.假設可以被6i,6i+2,  6i+4整除,也就是可以寫成2*(3i),  2*(3i+1),  2*(3i+2),那麼n一定也可以被2整除,那麼n一定是個偶數,但是很明顯6x-1,6x+1是奇數

2.假設能被6i+3整除,即可以寫成3*(2i+1),那麼n至少能被3整除,因爲對於一個連續的3個數,是不是一定有一個模3餘0,一個模3餘1,一個模3餘2,而因爲6x被3整除,所以6x+1,6x-1一定不會被3整除,所以不需要考慮

最終只剩下6i-1和6i+1,只需要判斷這兩個就行

bool isPrime( int num )  
{  
                 //兩個較小數另外處理  
                 if(num ==2|| num==3 )  
                                 return 1 ;  
                 //不在6的倍數兩側的一定不是質數  
                 if(num %6!= 1&&num %6!= 5)  
                                 return 0 ;  
                 int tmp =sqrt( num);  
                 //在6的倍數兩側的也可能不是質數  
                 for(int i= 5;i <=tmp; i+=6 )  
                                 if(num %i== 0||num %(i+ 2)==0 )  
                                                 return 0 ;  
                 //排除所有,剩餘的是質數  
                 return 1 ;  
}

轉載自: https://blog.csdn.net/codeswarrior/article/details/78053754

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章