Marc B的鏈接顯示了一個非常簡單的算法,它是正確的,由NSLogan編寫。我寫了一個小小的修改來顯示一些大小/速度的權衡。我以爲我會爲了利益而分享。
首先,代碼:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#define USE_BITS
#ifdef USE_BITS
#define alloc_prime char *prime = calloc(i/8,sizeof(*prime));
#define set_not_prime(x) prime[x/8]|= (1<<(x%8))
#define is_prime(x) (!(prime[x/8]&(1<<(x%8))))
#endif
#ifdef USE_CHAR
#define alloc_prime char *prime = calloc(i,sizeof(*prime));
#define set_not_prime(x) prime[x] = 1
#define is_prime(x) (prime[x] == 0)
#endif
#ifdef USE_SIZE_TYPE
#define alloc_prime size_t *prime = calloc(i,sizeof(*prime));
#define set_not_prime(x) prime[x] = 1
#define is_prime(x) (prime[x] == 0)
#endif
int main(){
int i;
printf("Find primes up to: ");
scanf("%i",&i);
clock_t start, stop;
double t = 0.0;
assert((start = clock())!=-1);
//create prime list
alloc_prime;
int c1, c2, c3;
if(!prime){
printf("Can't allocate %zu bytes!\n",i*sizeof(*prime));
exit(1);
}
//set 0 and 1 as not prime
set_not_prime(0);
set_not_prime(1);
//find primes then eliminate their multiples (0 = prime, 1 = composite)
for(c2 = 2;c2 <= (int)sqrt(i)+1;c2++){
if(is_prime(c2)){
c1=c2;
for(c3 = 2*c1;c3 <= i+1; c3 += c1){
set_not_prime(c3);
}
}
}
stop = clock();
t = (double) (stop-start)/CLOCKS_PER_SEC;
//print primes
for(c1 = 0; c1 < i+1; c1++){
if(is_prime(c1))printf("%i\n",c1);
// if(prime[c1] == 0) printf("%i\n",c1);
}
printf("Run time: %f\n", t); //print time to find primes
return 0;
}
(請原諒的定義USE_BITS當不準確的錯誤信息......)
我比較存儲布爾變量三種不同的方式, peoro建議。一種方法實際上使用位,第二種使用整個字節,而最後一種使用整個機器字。關於哪個最快的猜測可能是機器字方法,因爲每個標記/布爾值都是由你的機器自然處理的。時序計算素數最多100,000,000在我的機器如下:
位:3.8S 個字符:5.8S M-話:10.8s
有趣的是,即使所有的醜陋表示只有一位的布爾值所需的位移總體上仍然較快。我的推測是緩存和參考地點似乎超過額外的〜3條指令。另外,你最終會使用n位機器字方法的1/n的內存!
是的,簡單的Sieve速度很慢。如果您發佈了迄今爲止的內容,也許有人可以幫助您改進它。 – aschepler 2011-01-26 19:32:37
請將您的代碼發送到 – Elalfer 2011-01-26 19:33:08
5秒鐘的谷歌搜索:http://www.dreamincode.net/code/snippet3315.htm – 2011-01-26 19:33:56