在网上搜索后,我知道按位版本的eratosthenes 筛子非常有效。问题是我无法理解它使用的数学/方法。
我一直在忙的版本是这样的:
#define MAX 100000000
#define LIM 10000
unsigned flag[MAX>>6]={0};
#define ifc(n) (flag[n>>6]&(1<<((n>>1)&31))) //LINE 1
#define isc(n) (flag[n>>6]|=(1<<((n>>1)&31))) //LINE 2
void sieve() {
unsigned i, j, k;
for(i=3; i<LIM; i+=2)
if(!ifc(i))
for(j=i*i, k=i<<1; j<LIM*LIM; j+=k)
isc(j);
}
我理解的要点(如果我错了,请纠正我):
- 第 1 行中的语句检查数字是否为复合数。
- 第 2 行中的语句将数字“n”标记为复合数。
- 该程序将值 0 或 1 存储在 int 的位中。这往往会将内存使用量减少到 x/32。(x 是使用 int 来存储 0 或 1 而不是像我上面的解决方案中那样的大小)
到目前为止,我脑海中的要点:
- LINE 1 中的函数如何运作。确保数字是否为复合数的函数如何。
- LINE 2 中的功能如何设置该位。
- 我也开始知道按位筛在时间上也是有效的。是因为仅使用按位运算符还是其他原因也在起作用。
有什么想法或建议吗?