[英]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的绝对值小, -128
到127
,如果我没有记错,所以使用比较==
相同的情况下比较了超过128较小的值但从128,你会得到一个新的盒装Integer
为current
,并且与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.