第一步是认识到将其拆分为任意大小的块是微不足道的;并且您不需要每个数字的数组(或位域)。例如,如果您只关心从 100000 到 110000 的数字,那么要将所有可被 3 整除的数字标记为“非质数”,您可以执行“ for( index = 3 * (100000+3-1)/3; index < 110000; index += 3) {
”。对于更灵活的示例:
for( value = 2; value < sqrt( block_end_value-1); value++ ) {
for( index = value * (block_state_value+value -1)/value; index < block_end_value; index += value ) {
mark_not_prime(index - block_state_value);
}
}
第二步是要意识到你不需要关心每个数字(for( value = 2; value < sqrt( block_end_value-1); value++)
以上是低效的)。例如,如果您已经将可被 2 整除的数字标记为“非质数”,那么没有理由关心数字是否可被 4、6 或 8 整除;如果您已经将可被 3 整除的数字标记为“非质数”,则没有理由关心数字是否可被 6、9 或 12 整除;和......基本上你只想测试一个数字是否可以被另一个素数整除。这意味着要查找 100000 到 110000 范围内的素数,您首先要查找 0 到 sqrt(110000) 范围内的素数;如果你想找到 0 到 sqrt(110000) 范围内的素数,你想找到 0 到 sqrt(sqrt(110000)) 范围内的素数;和 ....
第三步是意识到可以通过复制重复模式来加速。您可以创建一个 2 位模式(表示“可被 2 整除”)并将这 2 位复制到任何地方。以同样的方式,您可以创建一个 6 位模式(表示“可被 2 或 3 整除”)并将这 6 位复制到任何地方。以同样的方式,您可以创建一个 39916800 位模式(表示“可被 2、3、4、5、6、7、8、9、10 和 11 整除”)并将该 39916800 位模式复制到任何地方。当然,没有什么能阻止您预先生成模式并将其存储在程序代码中。
第四步是意识到 2 的倍数太小而无法存储,并且通过不存储它们,您可以将所有表和模式(以及任何存储/预生成的模式)的内存消耗减半。
通过结合上面的第三步和第四步;表示“可被 2、3、4、5、6、7、8、9、10 和 11 整除”的预生成模式将花费 19958400 位,即大约 2.38 MiB。就其本身而言,该模式的第一部分也可用于查找从 1 到大于 11 的第一个素数(在本例中为从 1 到 13 的数字)的素数。
第五步,意识到如果你已经有一个模式,你可以用它找到“ N = the next "not marked yet" prime number
”,将现有模式复制N次,然后将N的倍数标记为“非素数”;并以更大的模式结束。例如; 如果你有一个模式表示“可被 2、3、4、5、6、7、8、9、10 和 11 整除”,你会跳过 12(因为根据现有模式它不是素数);复制该模式 13 次,然后将可被 13 整除的数字标记为“非质数”,最终得到一个表示“可被 2、3、4、5、6、7、8、9、10、11 整除的模式, 12 和 13"。
The sixth step is to realize that once you have a pattern large enough for the range you want, you can fill in the missing divisors without copying. For example, if you only want prime numbers in the range from 1 to 6227020800; then you can take a pattern representing "is divisible by 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 and 13" and then mark numbers that are divisible by prime numbers in the range from 14 to 6227020800 as "not prime".
通过结合以上所有;如果你想找到 1000000000 到 11000000000 范围内的素数;那么你首先要找到 1 到 sqrt(11000000000) 范围内的素数;为此,您将复制一个预先生成的模式并将其扩展,直到您有一个足够大的表来表示 1 到 sqrt(11000000000) 范围内的素数;然后复制该扩展模式并填写缺失的数字以生成表示从 1 到 sqrt(11000000000) 范围内的素数的表格;然后为 1000000000 到 11000000000 范围内的素数创建一个表,并通过将“扩展预生成模式”中的数据复制到其中来初始化内存,然后使用 1 到 sqrt(11000000000) 范围内的素数表来查找尚未并入“