问题
I'm trying to do a simple primality test in Python.
Accoding to Wikipedia, a primality test is the following:
Given an input number n, check whether any integer m from 2 to n − 1 divides n. If n is divisible by any m then n is composite, otherwise it is prime.
I started with ruling out the even numbers - with the exception of 2 - as candidates to prime
def prime_candidates(x):
odd = range(1, x, 2)
odd.insert(0, 2)
odd.remove(1)
return odd
Then writing a function to check for primes, according to the rules above.
def isprime(x):
for i in range(2, x-1):
if x % i == 0:
return False
else:
return True
And this is the main function, which iterates over a list of 8000 prime candidates and tests their primality
def main():
end = 8000
candidates = prime_candidates(end)
for i in candidates:
if isprime(i) and i < end:
print 'prime found ' + str(i)
The problem is that the isprime
function returns True for numbers that aren't primes.
回答1:
In brief, your isprime(x)
checks whether the number is odd, exiting right after if x % 2 == 0
.
Try a small change so that you would actually iterate:
def isprime(x):
for i in range(2, x-1):
if x % i == 0:
return False
else:
return True
Note that else:
is now part of the for
loop rather than if
statement.
回答2:
Have a look at the Miller–Rabin primality test if a probabilistic algorithm will suffice. You could also prove a number to be prime, with for instance Elliptic Curve Primality Proving (ECPP), but it takes more effort.
A simple trial division algorithm is the following
def prime(a):
return not (a < 2 or any(a % x == 0 for x in range(2, int(a ** 0.5) + 1)))
Edit: Here's a more educational version because the first solution is very condensed and perhaps harder to read:
from math import sqrt
def prime(a):
if a < 2: return False
for x in range(2, int(sqrt(a)) + 1):
if a % x == 0:
return False
return True
I've substituted in sqrt(a)
in place of a ** 0.5
to make things more clear. The square root is used to not look at more factors than we have to.
回答3:
Your function actually returns whether your number is odd.
Indeed, what you're doing is you're checking whether 2 divides your number, and return immediately. You never check for the other numbers.
What you need to do is take this return true out of the if's else clause and the for loop back into the main function body.
On a sidenote, If you're looking for the primes lower than a given number, you could store the primes you found in memory and then only try dividing you new number by those primes ! (because if d is composite and divides q, then p exists such that p is prime and p divides q).
回答4:
The problem is that you put return False
in the else
clause rather than at the end of the function. So your function will return right after the first divisor is checked, rather than going on to check other divisors.
Here is a simple primality test similar to yours:
def is_prime(n):
d = 2
while d * d <= n:
if n % d == 0:
return False
d += 1
return n > 1
来源:https://stackoverflow.com/questions/8019343/primality-test-in-python