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