如何修复海龟旋转中的溢出
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。
我正在用 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 左右突然出现故障
试试这个:
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。