Primality by trial division: Difference between revisions

no edit summary
No edit summary
Line 951:
7 is a prime number
8 is not a prime number
 
=={{header|Crystal}}==
Mathematicaly basis of Prime Generators
https://www.academia.edu/19786419/PRIMES-UTILS_HANDBOOK
https://www.academia.edu/42734410/Improved_Primality_Testing_and_Factorization_in_Ruby_revised
<lang ruby>require "big"
require "benchmark"
 
# the simplest PG primality test using the P3 prime generator
# reduces the number space for primes to 2/6 (33.33%) of all integers
 
def primep3?(n) # P3 Prime Generator primality test
# P3 = 6*k + {5, 7} # P3 primes candidates (pc) sequence
n = n.to_big_i
return n | 1 == 3 if n < 5 # n: 0,1,4|false, 2,3|true
return false if n.gcd(6) != 1 # 1/3 (2/6) of integers are P3 pc
p = typeof(n).new(5) # first P3 sequence value
until p > isqrt(n)
return false if n % p == 0 || n % (p + 2) == 0 # if n is composite
p += 6 # first prime candidate for next kth residues group
end
true
end
 
# PG primality test using the P5 prime generator
# reduces the number space for primes to 8/30 (26.67%) of all integers
 
def primep5?(n) # P5 Prime Generator primality test
# P5 = 30*k + {7,11,13,17,19,23,29,31} # P5 primes candidates sequence
n = n.to_big_i
return [2, 3, 5].includes?(n) if n < 7 # for small and negative values
return false if n.gcd(30) != 1 # 4/15 (8/30) of integers are P5 pc
p = typeof(n).new(7) # first P5 sequence value
until p > isqrt(n)
return false if # if n is composite
n % (p) == 0 || n % (p+4) == 0 || n % (p+6) == 0 || n % (p+10) == 0 ||
n % (p+12) == 0 || n % (p+16) == 0 || n % (p+22) == 0 || n % (p+24) == 0
p += 30 # first prime candidate for next kth residues group
end
true
end
 
# PG primality test using the P7 prime generator
# reduces the number space for primes to 48/210 (22.86%) of all integers
 
def primep7?(n)
# P7 = 210*k + {11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,
# 89,97,101,103,107,109,113,121,127,131,137,139,143,149,151,157,163,
# 167,169,173,179,181,187,191,193,197,199,209,211}
n = n.to_big_i
return [2, 3, 5, 7].includes?(n) if n < 11
return false if n.gcd(210) != 1 # 8/35 (48/210) of integers are P7 pc
p = typeof(n).new(11) # first P7 sequence value
until p > isqrt(n)
return false if
n % (p) == 0 || n % (p+2) == 0 || n % (p+6) == 0 || n % (p+8) == 0 ||
n % (p+12) == 0 || n % (p+18) == 0 || n % (p+20) == 0 || n % (p+26) == 0 ||
n % (p+30) == 0 || n % (p+32) == 0 || n % (p+36) == 0 || n % (p+42) == 0 ||
n % (p+48) == 0 || n % (p+50) == 0 || n % (p+56) == 0 || n % (p+60) == 0 ||
n % (p+62) == 0 || n % (p+68) == 0 || n % (p+72) == 0 || n % (p+78) == 0 ||
n % (p+86) == 0 || n % (p+90) == 0 || n % (p+92) == 0 || n % (p+96) == 0 ||
n % (p+98) == 0 || n % (p+102) == 0 || n % (p+110) == 0 || n % (p+116) == 0 ||
n % (p+120) == 0 || n % (p+126) == 0 || n % (p+128) == 0 || n % (p+132) == 0 ||
n % (p+138) == 0 || n % (p+140) == 0 || n % (p+146) == 0 || n % (p+152) == 0 ||
n % (p+156) == 0 || n % (p+158) == 0 || n % (p+162) == 0 || n % (p+168) == 0 ||
n % (p+170) == 0 || n % (p+176) == 0 || n % (p+180) == 0 || n % (p+182) == 0 ||
n % (p+186) == 0 || n % (p+188) == 0 || n % (p+198) == 0 || n % (p+200) == 0
p += 210 # first prime candidate for next kth residues group
end
true
end
 
# Newton's method for integer squareroot
def isqrt(n)
raise ArgumentError.new "Input must be non-negative integer" if n < 0
return n if n < 2
bits = n.bit_length
one = typeof(n).new(1) # value 1 of type self
x = one << ((bits - 1) >> 1) | n >> ((bits >> 1) + 1)
while (t = n // x) < x; x = (x + t) >> 1 end
x # output is same integer class as input
end
 
# Benchmarks to test for various size primes
 
p = 541
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep3?") { primep3?(p) }
b.report("primep5?") { primep5?(p) }
b.report("primep7?") { primep7?(p) }
puts
end
 
p = 1000003
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep3?") { primep3?(p) }
b.report("primep5?") { primep5?(p) }
b.report("primep7?") { primep7?(p) }
puts
end
 
p = 2147483647i32 # largest I32 prime
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep3?") { primep3?(p) }
b.report("primep5?") { primep5?(p) }
b.report("primep7?") { primep7?(p) }
puts
end
 
p = 4294967291u32 # largest U32 prime
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep3?") { primep3?(p) }
b.report("primep5?") { primep5?(p) }
b.report("primep7?") { primep7?(p) }
puts
end
 
p = 4294967311 # first prime > 2**32
Benchmark.ips do |b|
print "\np = #{p}"
b.report("primep3?") { primep3?(p) }
b.report("primep5?") { primep5?(p) }
b.report("primep7?") { primep7?(p) }
puts
end</lang>
{{out}}
<pre>p = 541
primep3? 290.17k ( 3.45µs) (± 2.76%) 1.35kB/op 1.64× slower
primep5? 476.47k ( 2.10µs) (± 1.75%) 802B/op fastest
primep7? 128.44k ( 7.79µs) (± 2.82%) 2.66kB/op 3.71× slower
 
p = 1000003
primep3? 11.24k ( 88.97µs) (± 2.34%) 33.9kB/op 2.48× slower
primep5? 21.91k ( 45.64µs) (± 2.88%) 16.6kB/op 1.27× slower
primep7? 27.83k ( 35.94µs) (± 2.68%) 11.9kB/op fastest
 
p = 2147483647
primep3? 105.11 ( 9.51ms) (± 3.25%) 3.89MB/op 5.56× slower
primep5? 317.49 ( 3.15ms) (± 2.40%) 1.2MB/op 1.84× slower
primep7? 584.92 ( 1.71ms) (± 3.09%) 591kB/op fastest
 
p = 4294967291
primep3? 168.56 ( 5.93ms) (± 2.39%) 2.17MB/op 2.69× slower
primep5? 349.24 ( 2.86ms) (± 2.86%) 1.03MB/op 1.30× slower
primep7? 454.08 ( 2.20ms) (± 2.62%) 739kB/op fastest
 
p = 4294967311
primep3? 84.61 ( 11.82ms) (± 2.35%) 4.68MB/op 5.02× slower
primep5? 248.62 ( 4.02ms) (± 2.21%) 1.54MB/op 1.71× slower
primep7? 424.61 ( 2.36ms) (± 2.73%) 813kB/op fastest
</pre>
 
=={{header|D}}==
Anonymous user