如何修复海龟旋转中的溢出

how to fix Overflow in turtle rotation

我正在用 turtle 尝试一些代码(只是为了好玩),当我尝试时我感到很惊讶:

import turtle
turtle.speed(0)
for i in range(0,100):
    for x in range(0,i):
        turtle.forward(5)
        turtle.left((2**x)*90)

这按预期正常工作,直到 i = 98 左右突然出现故障 这不应该发生,因为它总是乘以 90,所以它应该总是右转

试试这个:

import turtle
turtle.speed(0)
for i in range(40,100):
    for x in range(0,i):
        turtle.forward(5)
        turtle.left((2**x*90)%360)

使用模运算会将输出限制为 359

编辑:

操作在 turtle 库中溢出,not your script。因此,您可以在将操作发送给 turtle 之前安全地对操作取模。

在我的系统上,故障在迭代 50 次后开始。问题似乎是程序使用的大整数与乌龟使用的浮点数之间的差异。如果我们检测代码:

angle = 0

for i in range(55):
    for x in range(i):
        turtle.forward(5)
        turtle.left(2**x * 90)
        angle += 2**x * 90
        print(angle % 360, turtle.heading())

万事开头难:

90 90.0
180 180.0
0 0.0
90 90.0
270 270.0

但最终浮点不精确开始累积:

270 269.2593644676
270 269.0124859568
0 359.0124859568
180 179.0124859568
180 179.0124859568

并积累:

270 258.1498314817
270 254.1997753089
0 344.1997753089
180 164.1997753089
180 164.1997753089

最终失控:

90 42.5993259266
90 26.7991012355
180 116.7991012355
0 296.7991012355
0 296.7991012355

正如@alexelias 指出的那样,我们可以使用模数来解决这个问题,方法是为 turtle 提供一个随时间累积的不精确性较低的值:

turtle.speed('fastest')

for i in range(100):
    for x in range(i):
        turtle.forward(5)
        turtle.left((2**x % 4) * 90)

我们知道 360 / 90 == 4 而不是将整个值取模 360,所以我们只需将另一个值取模 4。