I’m trying to convert some C++ to Python.
The C++ can be found at
https://gist.github.com/1635288
from prime import prime
from fractions import gcd
from copy import copy
def phi(n, primes):
if n < 2:
return 0
if n in primes:
return n - 1
if (n & 1) == 0:
m = n >> 1
#return ~(m & 1) ? phi(m, primes) << 1 : phi(m, primes)
if ~(m & 1):
return phi(m, primes) << 1
else:
return phi(m, primes)
for i in primes:
if i > n:
break
if n % i:
continue
m = copy(i)
o = n / m
d = gcd(m, o)
#return d == 1 ? phi(m) * phi(o) : phi(m) * phi(o) * d / phi(d)
if d == 1:
return phi(m, primes) * phi(o, primes)
else:
return phi(m, primes) * phi(o, primes) * d / phi(d, primes)
primes = []
for i in range(3, 10000000, 2):
if prime(i):
primes.append(i)
for i in range(80, 90): # a test to see if I am getting correct results
print phi(i, primes)
# returns 64, 54, 80, 82, 48, 64, 84, 56, 80, 88
# should be 32, 54, 40, 82, 24, 64, 42, 56, 40, 88
Basically, the function returns correct phi values for odd n, but returns double the correct value for even n. I suspect that where I am going wrong is at
m = copy(i)
whereas the C++ is
int m = *p;
I have looked up Wikipedia and seen that this is defining m as the value p is pointing to. Is this the problem? If not, what is?
I think you should use
if not (m & 1), rather thatif ~(m & 1), since the former is a check for odd/even numbers, while the latter would only returnfalseif you pass -1 to it.Tilde (
~) is the bitwise negation operator. For integer values it holds that~x == -x-1, which in your case won’t happen at all.