首页 > 解决方案 > Python 是否在处理大量数字/列表时遇到问题,或者我的代码有问题?

问题描述

我有以下代码:

def main(n):
    sequence = []
    while n not in sequence:
        sequence.append(n)

        if n % 2 == 0:
            i = n / 2
        else:
            i = (n * 3) + 1
        n = int(i)

    print("Sequence length: " + str(len(sequence)-1))

n = int(input("Number: "))
main(n)

它从用户那里获取一个整数,然后计算该数字的“3x+1”(或“Collat​​z”)序列(有关详细信息,请参见http://www.ericr.nl/wondrous/index.html#part1)。然后它显示序列的长度。

为了确保我的代码按预期工作,我将我的结果与http://www.ericr.nl/wondrous/delrecs.html上的表格进行比较。“延迟”列似乎是序列长度,而“N”是输入的初始整数。我的代码为所有 'N' 值(我已经随机测试过)提供了正确的长度,最高可达 1,899148,184679(#92)。然而,对于“N”的下一个值(2,081751,768559,#93),它给出的长度为“385”(而不是“1437”)......对于“N”上的所有值也是如此(即我已经测试过)比桌面上的要大 - 我的代码给出的答案比他们所做的要小得多。

Python 是否存在可能导致此行为的大量问题,或者我的代码有问题?

我承认我并不完全理解“延迟记录”,或者实际上该网页上的大部分信息。但是,即使我的假设是错误的,即“延迟记录”只是此方法生成的序列的长度,我的代码会计算相同的值直到那个特定的数字似乎很奇怪......

我正在使用 Python 3.8.10,以防万一。

标签: pythonlargenumbercollatz

解决方案


在此过程中,您会遇到浮点错误。“但我使用的是整数!” 我听到你说,Python 在这条线上做了一个浮点除法:

i = n / 2

看起来足够无害,但改为整数除法解决了这个问题:

i = n // 2

在数百个值之后,其中一个除法会给您一个错误,该值比实际整数值小一些 epsilon,然后在您调用int(n).

编辑:在仔细检查我的最后一点以找到失败的值之后,我不太正确。实际发生的情况是,虽然由于 Python 的 BigInt 实现,整数除法总是准确的,但浮点除法却不是,因为它仍然使用常规浮点数来提高速度。如果您的数字足够大,那么根本没有足够的字节来准确存储数字,这将导致舍入错误。

有问题的数字是19981441939834942。用整数除法你得到9990720969917471,而浮点除法产生9990720969917472.0

这对于您使用的任何语言都是一个问题(除了大多数其他语言不允许您意外地对整数使用浮点除法),因此请确保使用整数除法!


推荐阅读