Python while循环从未停止过,即使它应该停止

Python while循环从未停止过,即使它应该停止,python,algorithm,while-loop,infinite-loop,Python,Algorithm,While Loop,Infinite Loop,我一直在学习一本关于算法的书中的一些练习(重点是Python),当我试图解决某个问题时,我会有奇怪的行为。这个练习相当简单,目标是从范围(n)生成一个随机整数k,然后通过一系列“是/否”问题找到这个数字。只要n不是太大,下面的代码就可以工作,但是当它太大时,我会得到一个无限循环。但这不应该发生,因为在最坏的情况下,步长最终将等于1,位置将向k的值爬行,直到位置==k 当我同时打印step_size和position时,似乎position在它变得太大时没有更新,所以我猜它与值变得近似和截断有关(

我一直在学习一本关于算法的书中的一些练习(重点是Python),当我试图解决某个问题时,我会有奇怪的行为。这个练习相当简单,目标是从
范围(n)
生成一个随机整数
k
,然后通过一系列“是/否”问题找到这个数字。只要
n
不是太大,下面的代码就可以工作,但是当它太大时,我会得到一个无限循环。但这不应该发生,因为在最坏的情况下,
步长最终将等于1,
位置
将向
k
的值爬行,直到
位置==k

当我同时打印
step_size
position
时,似乎
position
在它变得太大时没有更新,所以我猜它与值变得近似和截断有关(这就是为什么我试图显式地将其转换为long,实际上可能没有任何作用)。代码的某些次要部分是不必要的,但我想让它适用于general
n
。关于发生了什么,你有什么想法吗(你可能需要增加
n
才能得到我所说的行为)

来自随机导入范围
从数学导入单元
n=10**15
k=随机范围(n)
成功=错误
台阶尺寸=ceil(n/2.0)
位置=长(ceil(n/2.0))
印刷品(k)
当success==False时:
如果位置==k:
成功=正确
print(str(int(position))+'是k的值。)
elif k<位置:
步长=ceil(步长/2.0)
位置-=步长大小
打印(步长、位置)
其他:
步长=ceil(步长/2.0)
位置+=步长大小
打印(步长、位置)

您需要使用
位置+=long(步长)
位置-=long(步长)


您遇到了精度问题。确保您的值始终表示为整数(而不是浮点数)。Python整数具有任意精度,但浮点数不具有任意精度。

当程序进入无限循环时,
k
的值是多少?您确定您得到的是无限循环,而且它不仅速度慢吗?在Python 3中(将
long()
更改为
int()
),即使使用10**200,它也适用于我。也许Python2处理大整数的方式存在一些问题?只需使用
n=10**20
运行,它会不断重复
k=3868077989840615714
步长=1
位置=3.868077978984061e19
。当将1.0添加到数字3.868977978984061e19时,您基本上是在添加0,因为它没有所需的精度。如果我没弄错的话,你甚至可以在上面加上1000,但仍然看不到任何变化。:-)请参阅k值的差异,k值的最后一位为5714…这也应绕过浮点精度problem@holroy,准确地说,它涵盖了两种情况。这很有效。在我的代码中,Python将
position
转换为浮点以进行加法/减法运算,然后会失去精度吗?@dsaxton,确切地说,您在某一点上还不错,但随后又失去了精度,您可能需要使用long或使用类似
的东西来进行abs(position-k)
from random import randrange
from math import ceil

n = 10**15
k = randrange(n)

success = False
step_size = ceil(n / 2.0)
position = long(ceil(n / 2.0))

print(k)

while success == False:
    if position == k:
        success = True
        print(str(int(position)) + ' is the value of k.')
    elif k < position:
        step_size = ceil(step_size / 2.0)
        position -= step_size
        print(step_size, position)
    else:
        step_size = ceil(step_size / 2.0)
        position += step_size
        print(step_size, position)
  if position == k:
        success = True
        print(str((position)) + ' is the value of k.')
    elif k < position:
        step_size = ceil(step_size / 2.0)
        position -= long(step_size)
        print(step_size, position,k)
    else:
        step_size = ceil(step_size / 2.0)
        position += long(step_size)
        print(step_size, position)
11008769984569663730780658772914869218303604494435631537943840906720756507580926318660187453313745419228469341648307070867052432521026422402953409000922062458195678772749579263632191432518529106302726
11008769984569663730780658772914869218303604494435631537943840906720756507580926318660187453313745419228469341648307070867052432521026422402953409000922062458195678772749579263632191432518529106302726 is the value of k.