mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
lib/prime: Fix primality of some large integers [#13492].
* lib/prime.rb: Use accurate sqrt to insure all factors are tested. Patch by Marcus Stollsteimer. * test/test_prime.rb: Adapt test for timeout git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
825a1e939b
commit
68354c350a
2 changed files with 10 additions and 9 deletions
|
@ -35,7 +35,7 @@ class Integer
|
||||||
return self >= 2 if self <= 3
|
return self >= 2 if self <= 3
|
||||||
return true if self == 5
|
return true if self == 5
|
||||||
return false unless 30.gcd(self) == 1
|
return false unless 30.gcd(self) == 1
|
||||||
(7..Math.sqrt(self).to_i).step(30) do |p|
|
(7..Integer.sqrt(self)).step(30) do |p|
|
||||||
return false if
|
return false if
|
||||||
self%(p) == 0 || self%(p+4) == 0 || self%(p+6) == 0 || self%(p+10) == 0 ||
|
self%(p) == 0 || self%(p+4) == 0 || self%(p+6) == 0 || self%(p+10) == 0 ||
|
||||||
self%(p+12) == 0 || self%(p+16) == 0 || self%(p+22) == 0 || self%(p+24) == 0
|
self%(p+12) == 0 || self%(p+16) == 0 || self%(p+22) == 0 || self%(p+24) == 0
|
||||||
|
@ -445,7 +445,7 @@ class Prime
|
||||||
|
|
||||||
segment_min = @max_checked
|
segment_min = @max_checked
|
||||||
segment_max = [segment_min + max_segment_size, max_cached_prime * 2].min
|
segment_max = [segment_min + max_segment_size, max_cached_prime * 2].min
|
||||||
root = Integer(Math.sqrt(segment_max).floor)
|
root = Integer.sqrt(segment_max)
|
||||||
|
|
||||||
segment = ((segment_min + 1) .. segment_max).step(2).to_a
|
segment = ((segment_min + 1) .. segment_max).step(2).to_a
|
||||||
|
|
||||||
|
|
|
@ -174,20 +174,21 @@ class TestPrime < Test::Unit::TestCase
|
||||||
def test_eratosthenes_works_fine_after_timeout
|
def test_eratosthenes_works_fine_after_timeout
|
||||||
sieve = Prime::EratosthenesSieve.instance
|
sieve = Prime::EratosthenesSieve.instance
|
||||||
sieve.send(:initialize)
|
sieve.send(:initialize)
|
||||||
begin
|
|
||||||
# simulates that Timeout.timeout interrupts Prime::EratosthenesSieve#compute_primes
|
# simulates that Timeout.timeout interrupts Prime::EratosthenesSieve#compute_primes
|
||||||
def sieve.Integer(n)
|
class << Integer
|
||||||
n = super(n)
|
alias_method :org_sqrt, :sqrt
|
||||||
sleep 10 if /compute_primes/ =~ caller.first
|
end
|
||||||
return n
|
begin
|
||||||
|
def Integer.sqrt(n)
|
||||||
|
sleep 10 if /compute_primes/ =~ caller.first
|
||||||
|
org_sqrt(n)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_raise(Timeout::Error) do
|
assert_raise(Timeout::Error) do
|
||||||
Timeout.timeout(0.5) { Prime.each(7*37){} }
|
Timeout.timeout(0.5) { Prime.each(7*37){} }
|
||||||
end
|
end
|
||||||
ensure
|
ensure
|
||||||
class << sieve
|
class << Integer
|
||||||
remove_method :Integer
|
alias_method :sqrt, :org_sqrt
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue