[英]Checking divisibility for (sort of) big numbers in python
I've been writing a simple program in python that encodes a string into a number using Gödel's encoding . 我一直在用python写一个简单的程序,使用Gödel的编码将字符串编码成数字。 Here's a quick overview: you take the first letter of the string, find its position in the alphabet (a -> 1, b -> 2, ..., z -> 26) and raise the first prime number (2) to this power. 快速概览:获取字符串的第一个字母,找到其在字母表中的位置(a-> 1,b-> 2,...,z-> 26),然后将第一个质数(2)增大为这种力量。 The you take the second letter in the string and the second prime (3) and so on. 您将字符串中的第二个字母和第二个质数(3)取为此类推。 Here's the code: 这是代码:
import string, math
alphabet = list(string.ascii_lowercase)
def primes(n):
"Returns a list of primes up to n."
primes = [2, 3]
i = 5
while i < n:
l = math.ceil(math.sqrt(i))
k = math.ceil(math.sqrt(i+2))
for p in primes[:l]:
if i % p == 0:
break
else:
primes.append(i)
for p in primes[:k]:
if (i+2) % p == 0:
break
else:
primes.append(i+2)
i += 6
return primes
def Encode(string):
"Encodes a string using Godel's encoding."
enc = 1
p = primes(100)
for i in range(len(string)):
enc = enc*(p[i]**(alphabet.index(string[i])+1))
return enc
def Decode(code):
"Decodes a Godel's encoding into a string."
dec = ""
for i in primes(100):
count = 0
while code % i == 0:
code /= i
count += 1
if count == 0: #If we've found a prime that doesn't divide code,
#there are no more letters to be added.
break
else:
dec += alphabet[count-1]
return dec
The primes() function works for my intends and purposes and so does Encode(). primes()函数可以满足我的意图和目的,Encode()也可以。 Now Decode() is the interesting part. 现在,Decode()是有趣的部分。 It works for encodings up to ~15 digits long but starts doing some mystical stuff starting at ~20 digits. 它适用于最长约15位数的编码,但从约20位数开始开始进行一些神秘的工作。 So for instance it gives the right output for the encoding of "aaaaaaaaaaaaaa" but not for "python". 因此,例如,它为“ aaaaaaaaaaaaaaaaaa”的编码提供了正确的输出,但没有为“ python”提供正确的输出。 For big numbers it seems to execute the while code % i == 0
loop too many times (176 for the first letter of "python" when it should be just 16). 对于大数,似乎执行while code % i == 0
循环了太多次(“ python”的第一个字母为176,当它仅为16时)。
Is this just a problem with the mod function in python? 这仅仅是python中的mod函数的问题吗? Sounds strange as 20 digits isn't all that long for a computer. 听起来很奇怪,因为20位数字对于计算机来说还不够长。 Is there a mistake in my code? 我的代码有错误吗? Thanks for all the help. 感谢您的所有帮助。 I'm not a programmer myself but I'm trying to learn doing stuff like this. 我自己不是程序员,但我正在尝试学习做这样的事情。 Therefore any constructive criticism is welcome. 因此,欢迎任何建设性的批评。
/=
in Python 3 returns a double-precision floating point value. 在Python 3中, /=
返回双精度浮点值。 (As does math.ceil
, btw.) Floating point values do not have arbitrary precision. (与math.ceil
和btw一样。)浮点值没有任意精度。 You could use //=
instead. 您可以使用//=
代替。 That always results in an integer. 总是产生一个整数。 (It gives the floor of the result.) (它给出结果的下限。)
(I previously said that math.ceil was your main culprit. I don't think that's the case, but nonetheless, you probably shouldn't be using a floating point value to index into a list. If you need to run the same code in Python 2 that will fail. You can cast it back to an integer using int(math.ceil(...))
, although you might want to consider avoiding floating-point calculations altogether, since things will begin to break down for sufficiently large values.) (我之前说过math.ceil是您的主要罪魁祸首。我不认为是这种情况,但尽管如此,您可能不应该使用浮点值来索引到列表中。如果您需要运行相同的代码在Python 2中会失败。您可以使用int(math.ceil(...))
将其int(math.ceil(...))
转换为整数,尽管您可能要考虑完全避免使用浮点数计算,因为这样一来,事情就会开始分解大价值。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.