如何解决乌龟旋转中的溢出问题

时间:2019-05-19 02:15:57

标签: python turtle-graphics

我正在尝试用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左右突然突然出现故障为止 Glitch 这不应该发生,因为它总是乘以90,所以应该一直右转

2 个答案:

答案 0 :(得分:2)

尝试一下:

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

编辑:

该操作在turtlenot your script中溢出。这样您就可以安全地对操作进行模运算,然后再将其发送给turtle。

答案 1 :(得分:2)

在我的系统上,故障在迭代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.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。