简体   繁体   English

Eratosthenes的筛子认为127之后的所有数字都是素数

[英]Sieve of Eratosthenes thinks all numbers are prime after 127

I'm running into problems with my Sieve of Eratosthenes. 我的Eratosthenes筛网遇到问题。 I wanted to write a Sieve that didn't require an array of all numbers up to the largest prime you want, instead just keeping track of each prime multiple as the Sieve reaches it. 我想编写一个Sieve,它不需要由所有数字组成的数组,直到您想要的最大质数,而只是在Sieve到达时跟踪每个质数倍数。 That means you don't have to do all the work up front, but can just determine the next prime when you need it. 这意味着您不必先进行所有工作,而可以在需要时确定下一个质数。 It would also be easy to add interface features like "find K primes starting at N". 添加诸如“从N开始查找K素数”之类的接口功能也很容易。 Here is the pseudocode: 这是伪代码:

Begin with current number set to 2
Loop:
    If prime queue is not empty:
        Peek at the top prime in the queue
        If current > top, we can move top to the next multiple
            Remove the top prime from the prime queue
            Increment top to its next multiple
            Re-add it to the queue
        If current == top, current is not a prime
            Increment current number to next integer
        If current < top, we've found a prime
            Break
Push current number onto prime queue
Increment current number to next integer
Return the new prime

So here's the problem: I correctly calculate the first 31 primes (up to 127), but after that it thinks every number is prime. 所以这是问题所在:我正确计算了前31个素数(最大为127),但是之后它认为每个数字都是素数。 I've put my code on Ideone -- I'm hoping it's some Java collections behavior, or a trivial bug, rather than the algorithm itself. 我已经将代码放在Ideone上了-我希望它是某些Java集合行为或一个小错误,而不是算法本身。 I can't think of a reason the algorithm should break after a certain number of primes. 我想不出算法应在一定数量的素数后中断的原因。 I've confirmed manually that after 127, if the heap is properly ordered, my algorithm should recognize 128 as not a prime, but that's not what the code shows me. 我已经手动确认,在127之后,如果正确地对堆进行了排序,我的算法应该将128识别为不是素数,但这不是代码向我显示的内容。

Any suggestions? 有什么建议么?

http://ideone.com/E07Te http://ideone.com/E07Te

(I will, of course, increment by 2 (to skip all non-prime even numbers) once I get the basic algorithm working. I'll probably also make the Sieve an iterable.) (当然,一旦基本算法生效,我将增加2(以跳过所有非素数偶数)。我可能还会使Sieve成为可迭代的。)

Your problem is 你的问题是

top.multiple == current

in connection with 与...有关

Integer current = 2;
Integer multiple;

There is a cache of Integer s with small absolute value, -128 to 127 , if I recall correctly, so the comparison using == compares identical instances for values smaller than 128. But from 128 on, you get a new boxed Integer for current , and that is a different object than the one referenced by top.multiple . 还有就是缓存Integer s的绝对值小, -128127 ,如果我没有记错,所以使用比较==相同的情况下比较了超过128较小的值但从128,你会得到一个新的盒装Integercurrent ,并且与top.multiple引用的对象不同。

Compare using equals or declare int current; 使用equals比较或声明int current; to solve it. 解决它。

And improve your algorithm, note multiples of each prime only from the prime's square. 并改进您的算法,仅从素数的平方中记下每个素数的倍数。

You're not checking your whole list: 您没有检查整个列表:

Sieve heap after 31: [[127:127], [11:132], [2:128] 31之后的筛子堆:[[127:127],[11:132],[2:128]

You get to 132, which is > 128, and thus hit the break; 您到达132,即> 128,从而break; before you check for 2*64. 在您检查2 * 64之前。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM